如何使用 Coldfusion 访问 XML 数据
How to access XML data with Coldfusion
一位客户要我在他的网站上添加天气预报。官方天气预报包含在 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"
表示 'today',index="1"
表示 'tomorrow'。客户想要7天的outlook。
所以目前在所有 XML 数据中我需要确定它是关于哪一天的,图标代码(用于漂亮的图片)和 Precis(通常是一个单词或短语),probability_of_precipitation(会下雨吗?)和时间。剩下的我可以扔掉。
在另一个具有类似结构的文件中,有针对该页面的另一个版本的长格式预测。
我已经能够访问第一行(aac
和 description
)中的属性,但我需要帮助的是如何访问该行下的预测期元素。所有其他地区也有 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")>
returns 这个结构:
{
"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,然后使用常规 struct/array 处理。
您可以使用 1 行代码在 Adobe ColdFusion 中将 XML 转换为 JSON。
<cfset myJSONObject = createObject("java","org.json.XML").toJSONObject(XMLText)>
<cfdump var="#myJSONObject#">
有关更多示例,请在此处查看示例 CFML:
https://gist.github.com/JamoCA/00bb362672f772fab56d26f3e01ad3fa
一位客户要我在他的网站上添加天气预报。官方天气预报包含在 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"
表示 'today',index="1"
表示 'tomorrow'。客户想要7天的outlook。
所以目前在所有 XML 数据中我需要确定它是关于哪一天的,图标代码(用于漂亮的图片)和 Precis(通常是一个单词或短语),probability_of_precipitation(会下雨吗?)和时间。剩下的我可以扔掉。
在另一个具有类似结构的文件中,有针对该页面的另一个版本的长格式预测。
我已经能够访问第一行(aac
和 description
)中的属性,但我需要帮助的是如何访问该行下的预测期元素。所有其他地区也有 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")>
returns 这个结构:
{
"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,然后使用常规 struct/array 处理。
您可以使用 1 行代码在 Adobe ColdFusion 中将 XML 转换为 JSON。
<cfset myJSONObject = createObject("java","org.json.XML").toJSONObject(XMLText)>
<cfdump var="#myJSONObject#">
有关更多示例,请在此处查看示例 CFML: https://gist.github.com/JamoCA/00bb362672f772fab56d26f3e01ad3fa