如何使用Coldfusion访问XML数据



客户希望我在他的网站上添加天气预报。官方天气报告是一个XML文件,我需要帮助来访问文件中的一些元素。

我可以下载包含站点所需数据的两个XML文件,我可以将它们解析为ColdFusion XML变量。

我可以从顶层提取我需要的数据,但较低的层次让我有些心痛。XML文件包含该州每个位置的天气观测和预报。我们不需要那个,我们只是想访问我的客户的位置数据。

这里是我正在讨论的XML数据的示例

<area aac="NSW_PT123" description="Richmond" type="location" parent-aac="NSW_PW005">
<forecast-period index="0" start-time-local="2021-10-16T17:00:00+11:00" end-time-local="2021-10-17T00:00:00+11:00" start-time-utc="2021-10-16T06:00:00Z" end-time-utc="2021-10-16T13:00:00Z">
<element type="forecast_icon_code">2</element>
<text type="precis">Clear.</text>
<text type="probability_of_precipitation">5%</text>
</forecast-period>
<forecast-period index="1" start-time-local="2021-10-17T00:00:00+11:00" end-time-local="2021-10-18T00:00:00+11:00" start-time-utc="2021-10-16T13:00:00Z" end-time-utc="2021-10-17T13:00:00Z">
<element type="forecast_icon_code">1</element>
<element type="air_temperature_minimum" units="Celsius">7</element>
<element type="air_temperature_maximum" units="Celsius">24</element>
<text type="precis">Sunny.</text>
<text type="probability_of_precipitation">0%</text>
</forecast-period>
<forecast-period index="2" start-time-local="2021-10-18T00:00:00+11:00" end-time-local="2021-10-19T00:00:00+11:00" start-time-utc="2021-10-17T13:00:00Z" end-time-utc="2021-10-18T13:00:00Z">
<element type="forecast_icon_code">1</element>
<element type="air_temperature_minimum" units="Celsius">7</element>
<element type="air_temperature_maximum" units="Celsius">28</element>
<text type="precis">Sunny.</text>
<text type="probability_of_precipitation">5%</text>
</forecast-period>

在这段代码中,index="0"表示'今天',index="1"表示'明天'。客户需要7天的outlook。

因此,目前我需要从所有XML数据中确定日期、图标代码(用于漂亮的图片)和Precis(通常是单个单词或短语)、probability_of_precipitation(会下雨吗?)和时间。其余的我可以扔掉。

在另一个具有类似结构的文件中,有一个长格式预测页面的另一个版本。

我已经能够访问第一行(aacdescription)的属性,但我需要帮助的是如何访问该行下的预测周期元素。其他地区也有forecast-period元素,我们不想访问。

我使用ColdFusion XmlSearch/XPATH表达式

进入XML文件的这一部分
XmlSearch(IDN10064XML, "//area[@aac='NSW_PT123']")

我的问题是。在上面的示例代码中,(我无法控制-这是政府提供的)我如何创建一个变量来给我结果

  • "Clear."从上面的精确元素?
  • "5%"从降水要素的概率?
  • "2"从forecast_icon_code元素?
<cffunction name="WeatherForecast" returntype="struct">
<cfargument name="weatherData" type="xml" required="yes">
<cfargument name="areaCode" type="string" required="yes">
<cfset var areas = XmlSearch(weatherData, "//area[@aac='#areaCode#']")>
<cfif ArrayLen(areas) eq 0>
<cfthrow message="WeatherForecast: area code #areaCode# not found.">
</cfif>

<cfset var textOnly = function (node) {
return node.XmlType == 'ATTRIBUTE' ? node.XmlValue : node.XmlText;
}>
<cfreturn {
icons: XmlSearch(areas[1], "./forecast-period/element[@type='forecast_icon_code']").map(textOnly),
precis: XmlSearch(areas[1], "./forecast-period/text[@type='precis']").map(textOnly),
precipitation: XmlSearch(areas[1], "./forecast-period/text[@type='probability_of_precipitation']").map(textOnly)
}>
</cffunction>

用法:

<cfset IDN10064XML = XmlParse(weatherXml, true)>
<cfset forecast = WeatherForecast(IDN10064XML, "NSW_PT123")>

返回这个结构体:

{
"PRECIPITATION": ["5%", "0%", "5%"],
"PRECIS": ["Clear.", "Sunny.", "Sunny."],
"ICONS": ["2", "1", "1"]
}

每个部分包含的值与XML中<area><forecast-period>元素的数量一样多,按照它们在XML中出现的顺序。换句话说,forecast.precipitation[1]将指向"今天",除非XML有可能出现无序(我表示怀疑)。

像时间属性值这样的东西可以用同样的方式提取:

XmlSearch(areas[1], "./forecast-period/@start-time-local").map(textOnly)

我更喜欢将简单的XML转换为JSON,然后使用常规的结构/数组处理。

你可以在Adobe ColdFusion中使用1行代码将XML转换为JSON。

<cfset myJSONObject = createObject("java","org.json.XML").toJSONObject(XMLText)>
<cfdump var="#myJSONObject#">

更多示例,查看这里的示例CFML:https://gist.github.com/JamoCA/00bb362672f772fab56d26f3e01ad3fa

最新更新