web-dev-qa-db-fra.com

Erreur XML: il existe plusieurs éléments racine

J'obtiens XML d'un service Web. Voici à quoi ressemble le XML:

<parent>
    <child>
        Text
    </child>
</parent>
<parent>
    <child>
        <grandchild>
            Text
        </grandchild>
        <grandchild>
            Text
        </grandchild>
    </child>
    <child>
        Text
    </child>
</parent>

etc.

Et voici mon code C #:

StringBuilder output = new StringBuilder();

// Create an XmlReader
using (XmlReader reader = XmlReader.Create(new StringReader(xoResponse.@return)))
{
    XmlWriterSettings ws = new XmlWriterSettings();
    //ws.Indent = true;
    using (XmlWriter writer = XmlWriter.Create(output, ws))
    {
        // Parse the file and display each of the nodes.
        while (reader.Read())
        {
            switch (reader.NodeType)
            {
                case XmlNodeType.Element:
                    writer.WriteStartElement(reader.Name);
                    break;
                case XmlNodeType.Text:
                    writer.WriteString(reader.Value);
                    break;
                case XmlNodeType.XmlDeclaration:
                case XmlNodeType.ProcessingInstruction:
                    writer.WriteProcessingInstruction(reader.Name, reader.Value);
                    break;
                case XmlNodeType.Comment:
                    writer.WriteComment(reader.Value);
                    break;
                case XmlNodeType.EndElement:
                    writer.WriteFullEndElement();
                    break;
            }
        }
    }
}

Je crois que l'erreur est lancée sur le deuxième élément parent. Comment puis-je éviter cette erreur? Toute aide est grandement appréciée.

44
divided

Vous devez joindre votre <parent> les éléments d'un élément environnant en tant que documents XML ne peuvent avoir qu'un seul nœud racine:

<parents> <!-- I've added this tag -->
    <parent>
        <child>
            Text
        </child>
    </parent>
    <parent>
        <child>
            <grandchild>
                Text
            </grandchild>
            <grandchild>
                Text
            </grandchild>
        </child>
        <child>
            Text
        </child>
    </parent>
<parents> <!-- I've added this tag -->

Comme vous recevez ce balisage ailleurs, plutôt que de le générer vous-même, vous devrez peut-être le faire vous-même en traitant la réponse comme une chaîne et en l'enveloppant avec les balises appropriées, avant d'essayer de l'analyser en XML.

Donc, vous avez deux choix:

  1. Demandez au fournisseur du service Web de vous renvoyer réel XML qui a un nœud racine
  2. Prétraitez le XML, comme je l'ai suggéré ci-dessus, pour ajouter un nœud racine
  3. Prétraitez le XML pour le diviser en plusieurs morceaux (c'est-à-dire un pour chaque <parent> node) et les traiter chacun comme un document XML distinct
52
Rob

Vous pouvez le faire sans modifier le flux XML: dites au XmlReader de ne pas être aussi pointilleux. Réglage du XmlReaderSettings.ConformanceLevel à ConformanceLevel.Fragment laissera l'analyseur ignorer le fait qu'il n'y a pas de nœud racine.

        XmlReaderSettings settings = new XmlReaderSettings();
        settings.ConformanceLevel = ConformanceLevel.Fragment;
        using (XmlReader reader = XmlReader.Create(tr,settings))
        {
             ...
        }

Maintenant, vous pouvez analyser quelque chose comme ça (qui est un flux XML en temps réel, où il est impossible de boucler avec un nœud).

<event>
  <timeStamp>1354902435238</timeStamp>
  <eventId>7073822</eventId>
</event>
<data>
  <time>1354902435341</time>
  <payload type='80'>7d1300786a0000000bf9458b0518000000000000000000000000000000000c0c030306001b</payload>
</data>
<data>
  <time>1354902435345</time>
  <payload type='80'>fd1260780912ff3028fea5ffc0387d640fa550f40fbdf7afffe001fff8200fff00f0bf0e000042201421100224ff40312300111400004f000000e0c0fbd1e0000f10e0fccc2ff0000f0fe00f00f0eed00f11e10d010021420401</payload>
</data>
<data>
  <time>1354902435347</time>
  <payload type='80'>fd126078ad11fc4015fefdf5b042ff1010223500000000000000003007ff00f20e0f01000e0000dc0f01000f000000000000004f000000f104ff001000210f000013010000c6da000000680ffa807800200000000d00c0f0</payload>
</data>
72
Mark Lakata

Envelopper le xml dans un autre élément

<wrapper>
<parent>
    <child>
        Text
    </child>
</parent>
<parent>
    <child>
        <grandchild>
            Text
        </grandchild>
        <grandchild>
            Text
        </grandchild>
    </child>
    <child>
        Text
    </child>
</parent>
</wrapper>
9
BenCr

Si vous êtes en charge (ou avez un contrôle sur le service Web), demandez-leur d'ajouter un élément racine unique!

Si vous ne pouvez pas changer cela du tout, alors vous pouvez faire un peu de regex ou de fractionnement de chaînes pour analyser chacun et passer chaque élément à votre lecteur XML.

Alternativement, vous pouvez ajouter manuellement un élément racine indésirable, en préfixant une balise d'ouverture et en suffixant une balise de fermeture.

6
Sam Hogarth