27

自動生成された xml がいくつかありますが、xml の一部には複数の行が含まれる場合とそうでない場合があります。その結果、行が 1 つの場合は 1 つの json ノードが返され、複数の行がある場合は json ノードを含む配列が返されます。

XMLは次のようになります

<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 にシリアライズする場合

JsonConvert.SerializeXmlNode(xmldoc, Formatting.Indented);

最初のxmlはこれになります

{
    "List": {
        "Content": {
            "Row": {
                "@Index": "0",
                "Title": "Testing",
                "PercentComplete": "0",
                "DueDate": null,
                "StartDate": null
            }
        }
    }
}

そして2つ目はこれ

{
    "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"
            }]
        }
    }
}

明らかにわかるように、2 番目の行は本来あるべき配列ですが、最初の行ではありません。この種の問題に対する既知の回避策はありますか、または JSON を受信するフロントエンドにチェックを実装する必要がありますか (構造が非常に動的であるため、これは少し問題になります)。最良の方法は、json.net が常に配列を返すように強制する方法がある場合です。

4

6 に答える 6

11

この動作を次のように修正しました

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

少し汚れていますが動作します。私はまだ他のソリューションに興味があります!

于 2013-01-23T20:46:58.330 に答える
10

IvánPérezGómezに+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);
    }

そして、xpath で見つかった要素に json:Array 属性を追加するには:

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 配列としての単一の子ノードのサンプルです。

以下は、json 配列としての単一の子ノードのサンプルです。

于 2014-10-22T10:15:25.473 に答える
0

XDocument を使用して同じ問題が見つかりました

if (XDocument.Parse("5.0021.0045.00").Descendants("行").Count() > 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)
            {

            }
于 2018-01-27T13:48:52.853 に答える