2013-01-23 18 views
21

मेरे पास कुछ स्वत: जेनरेटेड एक्सएमएल हैं जहां एक्सएमएल के कुछ हिस्सों में कई पंक्तियां हो सकती हैं और कुछ नहीं हो सकती हैं। नतीजा यह है कि यदि एक पंक्ति है तो एक जेसन नोड वापस कर दिया जाता है और यदि मेरे पास एकाधिक पंक्तियां हैं तो जेसन नोड्स के साथ एक सरणी लौटा दी जाती है।JSON.Net एक्सएमएल सीरियलाइजेशन एरर

xmls इस

<List> 
    <Content> 
     <Row Index="0"> 
      <Title>Testing</Title> 
      <PercentComplete>0</PercentComplete> 
      <DueDate/> 
      <StartDate/> 
     </Row> 
    </Content> 
</List> 

या साथ एकाधिक पंक्तियों की तरह लग सकता है

<List> 
    <Content> 
     <Row Index="0"> 
      <Title>Update Documentation</Title> 
      <PercentComplete>0.5</PercentComplete> 
      <DueDate>2013-01-31 00:00:00</DueDate> 
      <StartDate>2013-01-01 00:00:00</StartDate> 
     </Row> 
     <Row Index="1"> 
      <Title>Write jQuery example</Title> 
      <PercentComplete>0.05</PercentComplete> 
      <DueDate>2013-06-30 00:00:00</DueDate> 
      <StartDate>2013-01-02 00:00:00</StartDate> 
     </Row> 
    </Content> 
</List> 

जब JSON करने के लिए इन serializing पहले एक्सएमएल इस

हो जाता है

JsonConvert.SerializeXmlNode(xmldoc, Formatting.Indented); 

का उपयोग कर

और दूसरा यह

{ 
    "List": { 
     "Content": { 
      "Row": [{ 
       "@Index": "0", 
       "Title": "Update Documentation", 
       "PercentComplete": "0.5", 
       "DueDate": "2013-01-31 00:00:00", 
       "StartDate": "2013-01-01 00:00:00" 
      }, { 
       "@Index": "1", 
       "Title": "Write jQuery example", 
       "PercentComplete": "0.05", 
       "DueDate": "2013-06-30 00:00:00", 
       "StartDate": "2013-01-02 00:00:00" 
      }] 
     } 
    } 
} 

के रूप में स्पष्ट रूप से एक दूसरे पर पंक्ति देखा जा सकता है एक सरणी के रूप में होना चाहिए, लेकिन पहले एक पर नहीं है। क्या इस तरह के मुद्दों पर कोई ज्ञात कामकाज है या क्या मुझे JSON प्राप्त करने वाले मेरे अग्रभाग में चेक को लागू करने की आवश्यकता है (संरचनाएं बहुत गतिशील हैं क्योंकि यह थोड़ा समस्याग्रस्त होगा)। सबसे अच्छा तरीका होगा अगर json.net को हमेशा सरणी वापस करने के लिए लागू करने का कोई तरीका है।

+0

मैं एक ही समस्या पाया कृपया एक और soluntion (लगता है अगर XDocument.Parse (" 5,00 21,00 45.00 ") .Descendants (" पंक्ति ")। गणना()> 1) { } अगर (XDocument.Parse (" 1,00 5,00 45,00 6,00 10,00 65,00 11,00 100,00 98.00 ") .Descendants (" पंक्ति ")। गणना()> 1) { } – pratik1020

उत्तर

9

मैं इस

// Handle JsonConvert array bug 
var rows = doc.SelectNodes("//Row"); 
if(rows.Count == 1) 
{ 
    var contentNode = doc.SelectSingleNode("//List/Content"); 
    contentNode.AppendChild(doc.CreateNode("element", "Row", "")); 

    // Convert to JSON and replace the empty element we created but keep the array declaration 
    returnJson = JsonConvert.SerializeXmlNode(doc).Replace(",null]", "]"); 
} 
else 
{ 
    // Convert to JSON 
    returnJson = JsonConvert.SerializeXmlNode(doc); 
} 

की तरह इस व्यवहार यह थोड़ा गंदा है ठीक किया था, लेकिन यह काम करता है। मुझे अभी भी अन्य समाधानों में दिलचस्पी है!

22

Json.NET प्रलेखन से: http://james.newtonking.com/projects/json/help/?topic=html/ConvertingJSONandXML.htm

आप एक नोड मजबूर कर सकते हैं एक्सएमएल नोड आप JSON करने के लिए परिवर्तित कर रहे हैं करने के लिए विशेषता json:Array='true' जोड़कर किसी सरणी के रूप में प्रदान किया जाना है। साथ ही, आपको एक्सएमएल हेडर xmlns:json='http://james.newtonking.com/projects/json' पर जेसन उपसर्ग नामस्थान घोषित करने की आवश्यकता है या अन्यथा आपको एक एक्सएमएल त्रुटि मिलेगी जिसमें कहा गया है कि जेसन उपसर्ग घोषित नहीं किया गया है।

xml = @"<person xmlns:json='http://james.newtonking.com/projects/json' id='1'> 
     <name>Alan</name> 
     <url>http://www.google.com</url> 
     <role json:Array='true'>Admin</role> 
     </person>"; 

जेनरेट किए गए उत्पादन:

{ 
    "person": { 
    "@id": "1", 
    "name": "Alan", 
    "url": "http://www.google.com", 
    "role": [ 
     "Admin" 
    ] 
    } 
} 
+0

यह दिलचस्प है, –

+0

साझा करने के लिए धन्यवाद कैसे एक ही बात है, लेकिन दूसरी तरह के आसपास के बारे में? जेसन से एक्सएमएल तक और कहें कि प्रत्येक सरणी तत्व के लिए एक के बजाय एक एक्सएमएल नोड में मैप किए गए सरणी को रखना चाहते हैं? – Devela

+0

जेसन: ऐरे = 'सत्य' त्रुटि देता है 'नेमस्पेस उपसर्ग' जेसन 'परिभाषित नहीं किया गया है' हालांकि .config फ़ाइल में उपयोग करते समय। – NullVoxPopuli

7

मेरी +1 इवान पेरेज को गोमेज़ देते और उपलब्ध कराने के कुछ कोड यहाँ अपने जवाब का समर्थन करने के:

अगले उदाहरण प्रलेखन द्वारा प्रदान की जाती है

जड़ नोड पर आवश्यक json.net नेमस्पेस जोड़ें:

private static void AddJsonNetRootAttribute(XmlDocument xmlD) 
    { 
     XmlAttribute jsonNS = xmlD.CreateAttribute("xmlns", "json", "http://www.w3.org/2000/xmlns/"); 
     jsonNS.Value = "http://james.newtonking.com/projects/json"; 

     xmlD.DocumentElement.SetAttributeNode(jsonNS); 
    } 

और JSON जोड़ने के लिए: xpath द्वारा पाया तत्वों को सरणी विशेषता:

Here is a sample of a single child node as a json array:

+1

यह दिलचस्प लगता है, निश्चित रूप से कुछ ऐसा है जो स्रोत –

+0

सहमत है, यह केवल एक फ़ील्ड या सरणी से निपटने से सुरक्षित समाधान होगा। कोको में, देशी जेसन सीरिएलाइज़र हमेशा एक ही बच्चे नोड के लिए एक सरणी बनाता है, और यह मुझे एक अधिक संगत दृष्टिकोण के रूप में महसूस करता है। –

0

मेरे समाधान:

private static void AddJsonArrayAttributesForXPath(string xpath, XmlDocument doc) 
    { 
     var elements = doc.SelectNodes(xpath); 



     foreach (var element in elements) 
     { 
      var el = element as XmlElement; 

      if (el != null) 
      { 

       var jsonArray = doc.CreateAttribute("json", "Array", "http://james.newtonking.com/projects/json"); 
       jsonArray.Value = "true"; 
       el.SetAttributeNode(jsonArray); 
      } 
     } 
    } 

यहाँ एक json सरणी के रूप में एक भी बच्चे को नोड का एक नमूना है: यदि जेसन कन्वर्ट काम नहीं करता है तो इसका इस्तेमाल न करें। पर्स एक्सएमएल शब्दकोशों/संग्रहों में और फिर जेसन में।कम से कम इस तरह आपको तत्व तत्वों में से कोई भी हार्ड कोड नहीं करना है।

private JsonResult AsJsonResult(XmlDocument result) 
    { 
     var kvp = new KeyValuePair<string, object>(result.DocumentElement.Name, Value(result.DocumentElement)); 

     return Json(kvp 
      , JsonRequestBehavior.AllowGet); 
    } 

    /// <summary> 
    /// Deserializing straight from Xml produces Ugly Json, convert to Dictionaries first to strip out unwanted nesting 
    /// </summary> 
    /// <param name="node"></param> 
    /// <returns></returns> 
    private object Value(XmlNode node) 
    { 
     dynamic value; 

     //If we hit a complex element 
     if (node.HasChildNodes && !(node.FirstChild is XmlText)) 
     { 
      //If we hit a collection, it will have children which are also not just text! 
      if (node.FirstChild.HasChildNodes && !(node.FirstChild.FirstChild is XmlText)) 
      { 
       //want to return a list of Dictionarys for the children's nodes 
       //Eat one level of the hierachy and return child nodes as an array 
       value = new List<object>(); 
       foreach (XmlNode childNode in node.ChildNodes) 
       { 
        value.Add(Value(childNode)); 
       } 
      } 
      else //regular complex element return childNodes as a dictionary 
      { 
       value = new Dictionary<string, object>(); 
       foreach (XmlNode childNode in node.ChildNodes) 
       { 
        value.Add(childNode.Name, Value(childNode)); 
       } 
      } 
     } 
     else //Simple element 
     { 
      value = node.FirstChild.InnerText; 
     } 

     return value; 
    } 
0
मिले ही XDocument

यदि का उपयोग कर समस्या

(XDocument.Parse ("5.0021.0045.00")। वंशज ("पंक्ति")। गणना()> 1) { }

  if (XDocument.Parse("<RUT3><row><FromKG>1.00</FromKG><ToKG>5.00</ToKG><Rate>45.00</Rate></row><row><FromKG>6.00</FromKG><ToKG>10.00</ToKG><Rate>65.00</Rate></row><row><FromKG>11.00</FromKG><ToKG>100.00</ToKG><Rate>98.00</Rate></row></RUT3>").Descendants("row").Count() > 1) 
      { 

      } 
संबंधित मुद्दे