Question

Je dois souvent traiter des documents XML qui contiennent des éléments espaces de noms, mais ne déclare pas l'espace de noms. Par exemple:

<root>
  <a:element/>
</root>

Parce que le préfixe « un » n'est jamais attribué un URI d'espace de noms, le document est invalide. Quand je charge un tel document XML en utilisant le code suivant:

using (StreamReader reader = new StreamReader(new FileStream(inputFileName,    
       FileMode.Open, FileAccess.Read, FileShare.ReadWrite))) {
            doc = XDocument.Load(reader, LoadOptions.PreserveWhitespace);
}

il jette une exception indiquant (à juste titre) que le document contient un espace de noms non déclaré et n'est pas bien formé.

Alors, puis-je prédéfinir préfixe d'espace de noms par défaut -> namespace URI paires pour l'analyseur à se replier sur? XmlNamespaceManager semble prometteur, mais ne savent pas comment l'appliquer à cette situation (ou si je peux).

Était-ce utile?

La solution

Vous pouvez créer un XmlReader avec un XmlParserContext qui connaît les espaces de noms; les travaux suivants pour XmlDocument et XDocument:

class SimpleNameTable : XmlNameTable {
    List<string> cache = new List<string>();
    public override string Add(string array) {
        string found = cache.Find(s => s == array);
        if (found != null) return found;
        cache.Add(array);
        return array;
    }
    public override string Add(char[] array, int offset, int length) {
        return Add(new string(array, offset, length));
    }
    public override string Get(string array) {
        return cache.Find(s => s == array);
    }
    public override string Get(char[] array, int offset, int length) {
        return Get(new string(array, offset, length));
    }
}
static void Main() {
    XmlNamespaceManager mgr = new XmlNamespaceManager(new SimpleNameTable());
    mgr.AddNamespace("a", "http://foo/bar");
    XmlParserContext ctx = new XmlParserContext(null, mgr, null,
        XmlSpace.Default);
    using (XmlReader reader = XmlReader.Create(
        new StringReader(@"<root><a:element/></root>"), null, ctx)) {

        XDocument doc = XDocument.Load(reader);

        //XmlDocument doc = new XmlDocument();
        //doc.Load(reader);
    }
}

Autres conseils

Miser sur la réponse précédente, vous pouvez conserver les préfixes d'espace de noms par le premier chargement dans un XmlDocument et l'analyse du OuterXml du XmlDocument dans un XDocument

XDocument LoadWithPrefix(Stream stream)
{
    XmlNamespaceManager mgr = new XmlNamespaceManager(new NameTable());
    mgr.AddNamespace("a", "http://foo/bar");
    XmlParserContext ctx = new XmlParserContext(null, mgr, null, XmlSpace.Default);
    using (XmlReader reader = XmlReader.Create(stream, null, ctx)) 
    {
        XmlDocument doc = new XmlDocument();
        doc.Load(reader);
        return XDocument.Parse(doc.OuterXml);
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top