Frage

Ich habe oft mit XML-Dokumenten umgehen, die Elemente enthalten Namespace, aber erklärt nicht den Namespace. Zum Beispiel:

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

Da das Präfix „a“ wird nie ein Namespace-URI zugeordnet ist, ist das Dokument ungültig. Wenn ich lade solch ein XML-Dokument mit dem folgenden Code:

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

es löst eine Ausnahme unter Angabe (zu Recht), dass das Dokument einen nicht deklarierten Namespace enthält und ist nicht wohlgeformt ist.

Also, ich kann Standard-Namespace-Präfix vordefinieren -> NamespaceURI Paare für den Parser zurückgreifen? XmlNamespaceManager sieht vielversprechend aus, aber nicht wissen, wie es zu dieser Situation anwenden (oder, wenn ich kann).

War es hilfreich?

Lösung

Sie können eine XmlReader mit einem XmlParserContext erstellen, die über den Namensraum kennt; die folgenden Werke für XmlDocument und 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);
    }
}

Andere Tipps

Auf der Grundlage der vorherigen Antwort, können Sie die Namespacepräfixe durch erste Laden in ein XmlDocument und Parsen der OuterXml des XmlDocument in ein XDocument bewahren

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);
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top