Question

J'ai des données XML (similaires à l'échantillon ci-dessous) et je veux lire les valeurs dans le code.

Pourquoi suis-je obligé de spécifier l'espace de noms par défaut pour accéder à chaque élément? Je m'attendais à ce que l'espace de noms par défaut soit utilisé pour tous les éléments.

Existe-t-il un moyen plus logique d'atteindre mon objectif?

Exemple de XML:

<?xml version="1.0" encoding="UTF-8"?>
<ReceiptsBatch xmlns="http://www.secretsonline.gov.uk/secrets">
    <MessageHeader>
        <MessageID>00000173</MessageID>
        <Timestamp>2009-10-28T16:50:01</Timestamp>
        <MessageCheck>BX4f+RmNCVCsT5g</MessageCheck>
    </MessageHeader>
    <Receipts>
        <Receipt>
            <Status>OK</Status>
        </Receipt>
    </Receipts>
</ReceiptsBatch>

Code pour lire les éléments XML que j'après:

XDocument xDoc = XDocument.Load( FileInPath );

XNamespace ns = "http://www.secretsonline.gov.uk/secrets";

XElement MessageCheck = xDoc.Element(ns+ "MessageHeader").Element(ns+"MessageCheck");
XElement MessageBody = xDoc.Element("Receipts");
Était-ce utile?

La solution

La théorie est que la signification du document n'est pas affectée par le choix par l'utilisateur de préfixes d'espace de noms. Tant que les données sont dans l'espace de noms http://www.secretsonline.gov.uk/secrets, peu importe que l'auteur choisit d'utiliser le préfixe "s", "secrets", "_x.cafe.babe", ou le préfixe "null" (c'est-à-dire l'espace de noms par défaut). Votre application ne devrait pas s'en soucier: ce n'est que l'URI qui compte. C'est pourquoi votre application doit spécifier l'URI.

Autres conseils

Comme suggéré par Cette réponse, vous pouvez le faire en supprimant tous les espaces de noms de la copie en mémoire du document. Je suppose que cela ne devrait être fait que si vous savez que vous n'aurez pas de collisions de nom dans le document résultant.

/// <summary>
/// Makes parsing easier by removing the need to specify namespaces for every element.
/// </summary>
private static void RemoveNamespaces(XDocument document)
{
    var elements = document.Descendants();
    elements.Attributes().Where(a => a.IsNamespaceDeclaration).Remove();
    foreach (var element in elements)
    {
        element.Name = element.Name.LocalName;

        var strippedAttributes =
            from originalAttribute in element.Attributes().ToArray()
            select (object)new XAttribute(originalAttribute.Name.LocalName, originalAttribute.Value);

        //Note that this also strips the attributes' line number information
        element.ReplaceAttributes(strippedAttributes.ToArray());
    }
}

Vous pouvez utiliser XmltexTreader.Namespaces propriété pour désactiver les espaces de noms lors de la lecture du fichier XML.

string filePath;
XmlTextReader xReader = new XmlTextReader(filePath);
xReader.Namespaces = false;
XDocument xDoc = XDocument.Load(xReader);

C'est ainsi que fonctionne le LINQ-TO-XML. Vous ne pouvez trouver aucun élément, s'il n'est pas dans l'espace de noms par défaut, et il en va de même pour ses descendants. Le moyen le plus rapide de se débarrasser de l'espace de noms est de supprimer le lien vers l'espace de noms de votre XML initial.

Notez que l'élément Receipts est également dans l'espace de noms http://www.secretsonline.gov.uk/secrets, alors le XNamespace serait également requis pour l'accès à l'élément:

XElement MessageBody = xDoc.Element(ns + "Receipts");

Comme alternative à l'utilisation des espaces de noms, notez que vous pouvez utiliser "xpath agnostique" d'espace de noms "en utilisant local-name() et namespace-uri(), par exemple

/*[local-name()='SomeElement' and namespace-uri()='somexmlns']

Si vous omettez le namespace-uri prédicat:

/*[local-name()='SomeElement']

Correspondrait ns1:SomeElement et ns2:SomeElement etc. imo je préférerais toujours XNamespace Dans la mesure du possible, et les cas d'utilisation pour l'espace de noms XPATH AGNOSTIQUE sont assez limités, par exemple pour l'analyse d'éléments spécifiques dans des documents avec des schémas inconnus (par exemple dans un bus de service), ou l'analyse du meilleur effort de documents où l'espace de noms peut changer (par exemple épreuve future, où le xmlns Modifications pour correspondre à une nouvelle version du schéma de document)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top