ASP - > Coldfusion Webservice XML

时间:2010-12-12 23:33:51

标签: asp.net xml web-services coldfusion

我从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>

非常感谢通过此恐怖节目提供的任何代码段或帮助

1 个答案:

答案 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中的字段名称与它复制到的查询中的列名完全相同。