2017-03-24 5 views
1

Je travaille sur un service dans lequel je transmets une requête JSON, j'ai besoin de la convertir en XML et de la comparer à certains schémas XML pour ensuite faire quelque chose.Problème de gestion des attributs lors de la conversion de JSON en XML en C#

Mon problème concerne les attributs. Par exemple, ma demande JSON est:

{ 
"BookingSearch_IN": { 
"MsgHeader": {  
    "MessageID": "ABC010101", 
    "ContextRecord": { 
    "ContextInfo": { 
     "ItineraryDetails": { 
     "ItinerarySeqNmbr": "1", 
     "StartDate": "2017-04-01", 
     "EndDate": "2017-04-14",    
     "LocationStart": { 
      "LocationContext": "AIRPORT", 
      "LocationCode": "MIA" 
     }, 
     "LocationEnd": { 
      "LocationContext": "AIRPORT", 
      "LocationCode": "MIA" 
     } 
     }, 
     "ExtraInfoList": { 
     "ExtraInfo": { 
      "Category": "CRUISE", 
      "Item": { 
      "Code": "SHIP_CODE", 
      "Value": "MAGIC" 
      } 
     } 
     }, 
     "_ResType": "Vacation" 
    } 
    } 
}, 
"_xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance", 
"_xmlns:cs": "http://MyCompany.com", 
"_version": "6.66", 
"__prefix": "cs" 
    } 
} 

J'utilise: XmlDocument doc = JsonConvert.DeserializeXmlNode(jsonObject); pour le convertir en XML. Le résultat est xml:

<BookingSearch_IN> 
<MsgHeader> 
    <MessageID>ABC010101</MessageID> 
     <ContextRecord> 
      <ContextInfo> 
       <ItineraryDetails> 
        <ItinerarySeqNmbr>1</ItinerarySeqNmbr> 
        <StartDate>2017-04-01</StartDate> 
        <EndDate>2017-04-14</EndDate>      
        <LocationStart> 
         <LocationContext>AIRPORT</LocationContext> 
         <LocationCode>MIA</LocationCode> 
        </LocationStart> 
        <LocationEnd> 
         <LocationContext>AIRPORT</LocationContext> 
         <LocationCode>MIA</LocationCode> 
        </LocationEnd> 
       </ItineraryDetails> 
       <ExtraInfoList> 
        <ExtraInfo> 
        <Category>CRUISE</Category> 
        <Item> 
         <Code>SHIP_CODE</Code> 
         <Value>MAGIC</Value> 
        </Item> 
        </ExtraInfo> 
       </ExtraInfoList> 
       <_ResType>Vacation</_ResType> 
      </ContextInfo> 
     </ContextRecord> 
</MsgHeader> 
<xsi>http://www.w3.org/2001/XMLSchema-instance</xsi><cs>http://MyCompany.com</cs><_version>6.66</_version><__prefix>cs</__prefix> 
</BookingSearch_IN> 

Le XML résultat possède les attributs de l'élément racine à la fin du document, comme un autre des éléments (between </MsgHeader> and </BookingSearch_IN>). Mon problème est que le service qui valide ce XML par rapport au XML d'autres clients vérifie ces attributs dans l'élément racine. Voici comment le code prévoit que le XML soit:

<?xml version="1.0" encoding="UTF-8"?> 
<cs:BookingSearch_IN xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cs="http://MyCompany.com" version="6.66"> 
    <MsgHeader> 
     <MessageID>ABC010101</MessageID> 
     <ContextRecord> 
      <ContextInfo ResType="Vacation"> 
       <ItineraryDetails> 
        <ItinerarySeqNmbr>1</ItinerarySeqNmbr> 
        <StartDate>2017-04-01</StartDate> 
        <EndDate>2017-04-14</EndDate>      
        <LocationStart> 
         <LocationContext>AIRPORT</LocationContext> 
         <LocationCode>MIA</LocationCode> 
        </LocationStart> 
        <LocationEnd> 
         <LocationContext>AIRPORT</LocationContext> 
         <LocationCode>MIA</LocationCode> 
        </LocationEnd> 
       </ItineraryDetails> 
       <ExtraInfoList> 
        <ExtraInfo> 
         <Category>CRUISE</Category> 
         <Item> 
          <Code>SHIP_CODE</Code> 
          <Value>MAGIC</Value> 
         </Item>  
        </ExtraInfo> 
       </ExtraInfoList> 
      </ContextInfo>   
     </ContextRecord> 
    </MsgHeader>   
</cs:BookingSearch_IN> 

Le code échoue parce qu'il attendre l'élément racine d'être <cs:BookingSearch_IN xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cs="http://MyCompany.com" version="5.22">

.... tout conseil sur la façon de gérer cette situation? ou comment remettre ces attributs à l'endroit où ils appartiennent dans l'élément racine?

Répondre

2

NewtonSoft s'attend à ce que les attributs soient préfixés avec @, et non _ ou __, et s'attend à ce que les préfixes soient juste cuits dans les noms. Par exemple, si vous pouvez obtenir votre JSON pour ressembler à ceci:

{ 
    "cs:BookingSearch_IN": { 
     "@xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance", 
     "@xmlns:cs": "http://MyCompany.com", 
     "@version": "6.66", 
     "MsgHeader": { 
      "MessageID": "ABC010101", 
      "ContextRecord": { 
       "ContextInfo": { 
        "@ResType": "Vacation", 
        "ItineraryDetails": { 
         "ItinerarySeqNmbr": "1", 
         "StartDate": "2017-04-01", 
         "EndDate": "2017-04-14", 
         "LocationStart": { 
          "LocationContext": "AIRPORT", 
          "LocationCode": "MIA" 
         }, 
         "LocationEnd": { 
          "LocationContext": "AIRPORT", 
          "LocationCode": "MIA" 
         } 
        }, 
        "ExtraInfoList": { 
         "ExtraInfo": { 
          "Category": "CRUISE", 
          "Item": { 
           "Code": "SHIP_CODE", 
           "Value": "MAGIC" 
          } 
         } 
        } 
       } 
      } 
     } 
    } 
} 

Il fonctionnera correctement (notez que vous devez déplacer ces années XMLNS jusqu'au sommet - si elles restent là où ils sont au fond, il laisse tomber le préfixe pour une raison quelconque).

Si cela n'est pas possible, vous devrez soit utiliser un sérialiseur différent, soit écrire une logique personnalisée pour pré/post-traiter votre fichier JSON ou XML.

+0

Comme j'avais besoin de tester mon code, j'ai googlé quelques outils en ligne pour convertir mon échantillon XML en JSON et voir si cela fonctionne. J'ai découvert qu'il n'y a pas de façon "standard" de représenter XML au format JSON. Un des sites Web a converti mon code XML en JSON avec les attributs de la même façon que vous avez répondu, juste après l'élément mais avec le préfixe "_". Je pense que je peux utiliser cet outil en ligne et juste remplacer le "_" pour "@". Je ne savais pas que NewtonSoft attendait "@" pour les attributs. Votre réponse a résolu mon problème ... merci pour l'info! –

+0

Je veux dire que 'DataContractJsonSerializer' utilise le' _'s ... Mais oui, il n'y a pas de standard, chaque sérialiseur a sa propre méthode. –