在Coldfusion中从XML中提取名称/值对

在Coldfusion中从XML中提取名称/值对,xml,coldfusion,Xml,Coldfusion,我需要从XML中获取键/值对,以填充网站上的成员信息。下面是XML的一个示例: <a:PObject xmlns:b="http://schemas.datacontract.org"> <b:CanUpsert>true</b:CanUpsert> <b:Fields xmlns:c="http://schemas.microsoft.com/2003/10/Serialization/Arrays"> <c:KeyValueOfs

我需要从XML中获取键/值对,以填充网站上的成员信息。下面是XML的一个示例:

<a:PObject xmlns:b="http://schemas.datacontract.org">
<b:CanUpsert>true</b:CanUpsert>
<b:Fields xmlns:c="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
    <c:KeyValueOfstringanyType>
        <c:Key>FirstName</c:Key>
        <c:Value i:type="d:long" xmlns:d="http://www.w3.org/2001/XMLSchema">Joe</c:Value>
    </c:KeyValueOfstringanyType>
    <c:KeyValueOfstringanyType>
        <c:Key>LastName</c:Key>
        <c:Value i:type="d:long" xmlns:d="http://www.w3.org/2001/XMLSchema">Mama</c:Value>
    </c:KeyValueOfstringanyType>
</b:Fields>
</a:PObject>

真的
名字
乔
姓氏
妈妈
我是XML新手,在前缀方面遇到了困难。我正在使用以下内容为我提供一个键/值对数组:

<cfset keyValue = xmlSearch(soapBody,"//*[local-name()='Key'] | //*[local-name()='Value']") />

我能够通过索引引用我需要的数据;这在大多数情况下都很有效,但由于某些原因,并非每个记录的数据都位于同一位置。也就是说,#keyValue[4]#在95%的记录中有效,但在少数记录中,它给了我一个完全不同的值

我在这里和其他地方读过很多关于这个主题的帖子;他们中没有人能让我绕过前缀问题。例如,我可以使用

<cfset firstNameKey = XmlSearch(soapBody,"//*[ text() = 'FirstName' ]") />

但是我如何得到相应的值呢?我试过使用以下兄弟姐妹,但一定没有正确地使用。。。我甚至试着去掉所有的前缀——之后什么都不起作用


提前非常感谢你们给我的任何建议。正如我所说的,我对XML是新手(在CF方面也没有那么先进),我期待着找到正确的方向。非常感谢

我建议使用一种比xpath更简单的方法—使用xmlparse()将XML字符串转换为对象,然后迭代所需的元素,使用cf代码构造名称-值对。Cfdump XML对象以查看结果结构的外观-应该非常简单。试试看

编辑

在这方面做了一些工作之后,我为您提供了一些工作代码:

<cfsavecontent variable="xmldata">
<PObject xmlns:b="http://schemas.datacontract.org">
<b:CanUpsert>true</b:CanUpsert>
<b:Fields xmlns:c="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
    <c:KeyValueOfstringanyType>
        <c:Key>FirstName</c:Key>
        <c:Value type="d:long" xmlns:d="http://www.w3.org/2001/XMLSchema">Joe</c:Value>
    </c:KeyValueOfstringanyType>
    <c:KeyValueOfstringanyType>
        <c:Key>LastName</c:Key>
        <c:Value type="d:long" xmlns:d="http://www.w3.org/2001/XMLSchema">Mama</c:Value>
    </c:KeyValueOfstringanyType>
</b:Fields>
</PObject>
</cfsavecontent>

<cfset xmlObj = xmlParse(xmldata)>
<cfset valueArray = xmlSearch(xmlObj,"//*[local-name()='KeyValueOfstringanyType']")>
<cfset nameValuePairs = {}>
<cfloop from="1" to="#ArrayLen(valueArray)#" index="i">
        <cfset name = xmlSearch(valueArray[i], "c:Key")[1].xmlText>
        <cfset value = xmlSearch(valueArray[i], "c:Value")[1].xmlText>
        <cfset nameValuePairs[name] = value>
</cfloop>
<cfdump var="#nameValuePairs#">

真的
名字
乔
姓氏
妈妈

注意,我不得不稍微修改您的xml示例,因为有一些对名称空间的引用没有定义。无论如何,上面的方法对我来说很有效。

我建议使用一种比xpath更简单的方法——使用xmlparse()将XML字符串转换为对象,然后使用cf代码迭代所需的元素,以构造名称-值对。Cfdump XML对象以查看结果结构的外观-应该非常简单。试试看

编辑

在这方面做了一些工作之后,我为您提供了一些工作代码:

<cfsavecontent variable="xmldata">
<PObject xmlns:b="http://schemas.datacontract.org">
<b:CanUpsert>true</b:CanUpsert>
<b:Fields xmlns:c="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
    <c:KeyValueOfstringanyType>
        <c:Key>FirstName</c:Key>
        <c:Value type="d:long" xmlns:d="http://www.w3.org/2001/XMLSchema">Joe</c:Value>
    </c:KeyValueOfstringanyType>
    <c:KeyValueOfstringanyType>
        <c:Key>LastName</c:Key>
        <c:Value type="d:long" xmlns:d="http://www.w3.org/2001/XMLSchema">Mama</c:Value>
    </c:KeyValueOfstringanyType>
</b:Fields>
</PObject>
</cfsavecontent>

<cfset xmlObj = xmlParse(xmldata)>
<cfset valueArray = xmlSearch(xmlObj,"//*[local-name()='KeyValueOfstringanyType']")>
<cfset nameValuePairs = {}>
<cfloop from="1" to="#ArrayLen(valueArray)#" index="i">
        <cfset name = xmlSearch(valueArray[i], "c:Key")[1].xmlText>
        <cfset value = xmlSearch(valueArray[i], "c:Value")[1].xmlText>
        <cfset nameValuePairs[name] = value>
</cfloop>
<cfdump var="#nameValuePairs#">

真的
名字
乔
姓氏
妈妈

注意,我不得不稍微修改您的xml示例,因为有一些对名称空间的引用没有定义。无论如何,以上这些对我来说很有用。

你好,杰克,谢谢你的回复!我想知道我现在是否在这样做,至少是部分?我从连接到的API获取XML,并按如下方式解析它:。当我转储“soapBody”时,我得到了一个漂亮的大格式XML表示。当我去掉名称空间并cfdump它时,我得到了一个看起来像一个巨大字符串的东西,带有标记和所有内容,但没有XML格式。不过,让我来研究一下你的建议,看看我有什么想法。非常感谢,杰克!嗯,仍然面临着同样的问题。我可以通过引用它的文本值“First Name”来访问First Name。但是我不知道如何访问Joe,因为我不知道它的值是什么,我所要做的就是。我现在正在做这件事,不过会给你回复的。谢谢你,杰克!你好,杰克,非常感谢你的帮助。实际上,我也想到了一种非常类似的方法,但我的方法使用了一堆cfif标记。你的效率更高。谢谢你的帮助!我真的很感激,没问题!所以是否将此标记为“已批准”答案?谢谢你好,杰克,谢谢你的回复!我想知道我现在是否在这样做,至少是部分?我从连接到的API获取XML,并按如下方式解析它:。当我转储“soapBody”时,我得到了一个漂亮的大格式XML表示。当我去掉名称空间并cfdump它时,我得到了一个看起来像一个巨大字符串的东西,带有标记和所有内容,但没有XML格式。不过,让我来研究一下你的建议,看看我有什么想法。非常感谢,杰克!嗯,仍然面临着同样的问题。我可以通过引用它的文本值“First Name”来访问First Name。但是我不知道如何访问Joe,因为我不知道它的值是什么,我所要做的就是。我现在正在做这件事,不过会给你回复的。谢谢你,杰克!你好,杰克,非常感谢你的帮助。实际上,我也想到了一种非常类似的方法,但我的方法使用了一堆cfif标记。你的效率更高。谢谢你的帮助!我真的很感激,没问题!所以是否将此标记为“已批准”答案?谢谢