2010-12-12 56 views
1

Je récupère le XML suivant à partir d'un service web ASP-NET (cela m'a pris seulement 3 jours). Mais parce que je suis un tel nube XML, je ne sais pas comment le formater dans une table d'affichage de base. J'ai besoin d'être en coldfusion car c'est tout ce que je comprends et mon site est un site des FC. Il utilise diffgram dont je ne sais rien non plus. Mais, je suis prêt à apprendre!ASP -> Coldfusion Webservice XML

<?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> 

Tout extrait de code ou de l'aide à travers ce spectacle d'horreur serait grandement apprécié

Répondre

3

Normalement, lorsque la consommation d'un webservice SOAP de ColdFusion que vous utilisez <cfinvoke> et les choses allaient revenir dans un format proche à natif.

Cependant, et en particulier lorsque je consomme des services Web ASP.NET ASMX, j'ai constaté que l'analyseur XML renvoyé et l'analyseur ColdFusion ne sont pas toujours symétriques; donc j'ai tendance à faire le traitement manuellement.

Ce code provient d'une méthode que j'ai écrite pour effectuer des appels d'API. Tout d'abord, faire la requête HTTP manuellement:

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

vérifier ensuite les conditions d'erreur communes: (vous pouvez rencontrer quelques messages/tout-de/pas-de/plus-que ceux-ci)

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

Ensuite, analyser le xml retourné, et revenir seulement la partie qui vous intéresse:

<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 /> 

Ce serait retourner le nœud <BillingResponse> et tout à l'intérieur.

Ensuite, vous devez analyser cela pour les données dont vous avez besoin. Vous pouvez le faire avec les expressions XPath et la fonction XMLSearch, ou si les données sont simples, il suffit de les saisir manuellement.

Le fichier XML DiffGram que vous référencez est probablement dû au fait que vous renvoyez un objet DataTable dans votre code .Net. Voici comment je gère que ColdFusion:

dataContainer = apiRequest(whatever); //calls the method above 

d'abord, assurez-vous qu'il ya des éléments de l'enfant pour obtenir:

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. 

ensuite obtenir le tableau d'éléments enfants:

local.items = local.dataContainer.DocumentElement.XmlChildren; 

Dans mon cas , Je crée une requête, donc j'ajoute assez de lignes à la requête pour contenir toutes les données:

//create enough rows in the query to store the contact data 
QueryAddRow(local.emptySet, arrayLen(local.items)); 

Parcourez ensuite chaque noeud dans le tableau d'éléments enfants, en copiant la valeur dans la requête. La variable local.fieldList est une liste de nœuds xml à l'intérieur de chaque ligne de votre DataTable, et elle utilisera la liste pour obtenir chaque champ. La boucle externe parcourt les lignes du DataTable et la boucle interne parcourt les colonnes de la ligne. J'ai supprimé beaucoup de ma liste pour garder le code relativement petit, mais il n'y a aucun problème à rendre la liste plus volumineuse.

//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; 

Oh, et cela suppose aussi que les noms de champs dans votre DataTable sont exactement les mêmes que les noms de colonnes dans la requête qu'il est les copier.

+0

Merci Adam!Êtes-vous sûr que est correct? Le bloc cfcatch directement en dessous est-il déclenché? Mais pas si je commente la ligne ci-dessus. Très probablement quelque chose que je fais mal cependant. – user460114

+0

Hm, je pense que cela devrait le faire: ''. J'ai également mis à jour le bloc de code dans la réponse ci-dessus. –

+0

Oui, l'erreur disparaît avec ce changement, tant que j'ajoute? WSDL dans l'URL. Sinon, j'ai toujours l'erreur. Je suis confus à propos de cette partie: dataContainer = apiRequest (quelquechose); Quelles variables remplacent ici? – user460114