我从ASP-NET网络服务中获取以下XML(仅此一次花了我3天)。但是因为我是一个这样的XML nube,我不知道如何将它格式化为基本的显示表。我需要它在coldfusion中,因为这是我所理解的,我的网站是CF网站。它使用diffgram,我也一无所知。但是,我已经准备好学习了!
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Body>
<BillingResponse xmlns="http://portal/customer.asmx">
<BillingResult>
<xs:schema id="NewDataSet" xmlns="" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element msdata:IsDataSet="true" msdata:UseCurrentLocale="true" name="NewDataSet">
<xs:complexType>
<xs:choice maxOccurs="unbounded" minOccurs="0">
<xs:element name="Table">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="CustomerCode" type="xs:int"/>
<xs:element minOccurs="0" name="ServiceCode" type="xs:int"/>
<xs:element minOccurs="0" name="SubscriberCode" type="xs:string"/>
<xs:element minOccurs="0" name="Status" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
<diffgr:diffgram xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<NewDataSet xmlns="">
<Table diffgr:id="Table1" msdata:rowOrder="0">
<CustomerCode>1114309</CustomerCode>
<ServiceCode>0</ServiceCode>
<SubscriberCode/>
<Status/>
</Table>
<Table diffgr:id="Table2" msdata:rowOrder="1">
<CustomerCode>1114309</CustomerCode>
<ServiceCode>2</ServiceCode>
<SubscriberCode>95205292</SubscriberCode>
<Status>OPEN</Status>
</Table>
<Table diffgr:id="Table3" msdata:rowOrder="2">
<CustomerCode>1114309</CustomerCode>
<ServiceCode>8</ServiceCode>
<SubscriberCode>dageorgetti</SubscriberCode>
<Status>1</Status>
</Table>
<Table diffgr:id="Table4" msdata:rowOrder="3">
<CustomerCode>1114309</CustomerCode>
<ServiceCode>16</ServiceCode>
<SubscriberCode>NTL00711</SubscriberCode>
<Status>CLOSED</Status>
</Table>
<Table diffgr:id="Table5" msdata:rowOrder="4">
<CustomerCode>1114309</CustomerCode>
<ServiceCode>16</ServiceCode>
<SubscriberCode>95205292</SubscriberCode>
<Status>CLOSED</Status>
</Table>
<Table diffgr:id="Table6" msdata:rowOrder="5">
<CustomerCode>1114309</CustomerCode>
<ServiceCode>16</ServiceCode>
<SubscriberCode>95205292</SubscriberCode>
<Status>OPEN</Status>
</Table>
<Table diffgr:id="Table7" msdata:rowOrder="6">
<CustomerCode>1114309</CustomerCode>
<ServiceCode>4096</ServiceCode>
<SubscriberCode>64280452637</SubscriberCode>
<Status>OPEN</Status>
</Table>
<Table diffgr:id="Table8" msdata:rowOrder="7">
<CustomerCode>1114309</CustomerCode>
<ServiceCode>4096</ServiceCode>
<SubscriberCode>64280426643</SubscriberCode>
<Status>OPEN</Status>
</Table>
</NewDataSet>
</diffgr:diffgram>
</BillingResult>
</BillingResponse>
</soap:Body>
</soap:Envelope>
非常感谢通过此恐怖节目提供的任何代码段或帮助
答案 0 :(得分:3)
通常,当从ColdFusion使用SOAP Web服务时,您将使用<cfinvoke>
,并且会以接近原生的格式返回。
但是,特别是在使用ASP.NET ASMX Web服务时,我发现返回的XML和ColdFusion的解析器并不总是很好用;所以我倾向于手动处理。
此代码来自我编写的用于调用API的方法。首先,手动发出HTTP请求:
<cftry>
<cfhttp
url="#wsLocation#"
result="local.wsResult"
method="post"
timeout="#variables.timeout#"
throwonerror="true"
>
<cfhttpparam type="formfield" name="inputName" value="inputValue" />
<cfhttpparam type="formfield" name="inputName" value="inputValue" />
<cfhttpparam type="formfield" name="inputName" value="inputValue" />
</cfhttp>
然后检查常见的错误情况:(你可能遇到一些/全部/无/超过这些)
<cfif trim(local.wsResult.fileContent) eq "Connection Timeout">
<cfthrow message="Request timeout while connecting to .Net API" detail="#local.wsResult.statusCode#" />
</cfif>
<cfif not isXML(local.wsResult.FileContent)>
<cfthrow message="ASP.NET WS did not return valid XML." detail="#local.wsResult.FileContent#" />
</cfif>
然后,解析返回的xml,并只返回您感兴趣的部分:
<cfset local.wsResponse = xmlParse(local.wsResult.Filecontent) />
<cfset local.rspContainer = local.wsResponse['soap:envelope']['soap:body'].BillingResponse.BillingResult />
<cfcatch>
<cfset local.arguments = arguments />
<cfset errorEmail(cfcatch, local) />
<cfreturn "" />
</cfcatch>
</cftry>
<cfreturn local.rspContainer />
这会返回<BillingResponse>
节点及其中的所有内容。
然后您需要解析所需的数据。您可以使用XPath表达式和XMLSearch
函数来完成,或者如果数据很简单,只需手动抓取它。
您引用的DiffGram xml可能是因为您在.Net代码中返回了一个DataTable对象。以下是我在ColdFusion中处理的方法:
dataContainer = apiRequest(whatever); //calls the method above
首先确保要获得子元素:
local.emptySet = QueryNew("GivenName,Surname,FileAs,CompanyName");
if (not structKeyExists(local.dataContainer, "DocumentElement")){ return local.emptySet; }
//emptySet is whatever object you're converting the xml into, only with no data, so
//maybe an empty query or structure or something.
然后获取子元素数组:
local.items = local.dataContainer.DocumentElement.XmlChildren;
在我的情况下,我正在创建一个查询,所以我在查询中添加了足够的行来保存所有数据:
//create enough rows in the query to store the contact data
QueryAddRow(local.emptySet, arrayLen(local.items));
然后遍历子元素数组中的每个节点,将值复制到查询中。变量local.fieldList
是DataTable中每行内的xml节点列表,它将使用该列表来获取每个字段。外部循环遍历DataTable中的行,内部循环遍历行中的列。我已经从我的列表中删除了很多以保持代码相对较小,但是使列表变大没有问题。
//popuplate the query
for (local.i = 1; local.i lte arrayLen(local.items); local.i = local.i + 1){
local.fieldList = "GivenName,Surname,FileAs,CompanyName";
for (local.j = 1; local.j lte listLen(local.fieldList); local.j = local.j + 1){
local.key = listGetAt(local.fieldList, local.j);
if (structKeyExists(local.items[local.i], local.key)){
QuerySetCell(local.emptySet, local.key, local.items[local.i][local.key].XmlText, local.i);
}
}
}
return local.emptySet;
哦,这也假设您的DataTable中的字段名称与它复制到的查询中的列名完全相同。