xml php - wie man Namespaces mit XPath ignoriert




simplexml parsing (4)

Sie können dasselbe in XPath2.0 in einer weniger ausführlichen Syntax tun:

/path/to/*:somenode

Mein Ziel ist es, bestimmte Knoten aus mehreren XML-Dateien mit mehreren Namespaces mit XPath zu extrahieren. Alles funktioniert gut, solange ich die Namespace-URIs kenne. Der Namespace-Name selbst bleibt konstant, aber die Schemas (XSD) sind manchmal clientgeneriert, dh mir unbekannt. Dann habe ich im Wesentlichen drei Möglichkeiten:

  1. Verwenden Sie nur ein Schema für den Namespace, in der Hoffnung, dass nichts schiefgeht (kann ich mir sicher sein?)

  2. Holen Sie die Children-Knoten des Dokuments und suchen Sie nach dem ersten Knoten mit einem Namespace-URI, in der Hoffnung, dass es dort ist und nur den URI verwenden, in der Hoffnung, dass es der richtige ist. kann aus mehreren Gründen schief gehen

  3. Irgendwie sage ich XPath: "Schau, ich interessiere mich nicht für die Namespaces, finde nur ALLE Knoten mit diesem Namen, ich kann dir sogar den Namen des Namespace nennen, nur nicht den URI". Und das ist die Frage hier ...

Dies ist keine Wiederholung von zahlreichen "Mein xpath-Ausdruck funktioniert nicht, da ich keine Namespace-Awareness kenne" -Fragen wie here oder here . Ich weiß, wie man das Namespace-Bewusstsein nutzt. Einfach nicht, wie man es los wird.


Sie können die XPath-Funktion local-name() verwenden. Anstatt einen Knoten wie zu wählen

/path/to/x:somenode

Sie können alle Knoten auswählen und nach dem Knoten mit dem korrekten lokalen Namen filtern:

/path/to/*[local-name() = 'somenode']

Sie könnten Namespace = false für einen XmlTextReader verwenden

[TestMethod]
public void MyTestMethod()
{
    string _withXmlns = @"<?xml version=""1.0"" encoding=""utf-8""?>
<ParentTag xmlns=""http://anyNamespace.com"">
<Identification value=""ID123456"" />
</ParentTag>
";

    var xmlReader = new XmlTextReader(new MemoryStream(Encoding.Default.GetBytes(_withXmlns)));

    xmlReader.Namespaces = false;

    var content = XElement.Load(xmlReader);

    XElement elem = content.XPathSelectElement("/Identification");

    elem.Should().NotBeNull();
    elem.Attribute("value").Value.Should().Be("ID123456");
}

mit:

using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Xml.XPath;
using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;

Wie Jeppe Stig Nielsen said , hat dieser Thread bereits gute Antworten, aber ich denke, dass diese offensichtliche Subtilität auch erwähnenswert ist.

using Anweisungen, die in Namespaces angegeben sind, kann zu einem kürzeren Code führen, da sie nicht wie bei der externen Angabe vollständig qualifiziert sein müssen.

Das folgende Beispiel funktioniert, weil die Typen Foo und Bar sich beide im selben globalen Namespace Outer .

Angenommen, die Codedatei Foo.cs :

namespace Outer.Inner
{
    class Foo { }
}

Und Bar.cs :

namespace Outer
{
    using Outer.Inner;

    class Bar
    {
        public Foo foo;
    }
}

Das kann den äußeren Namespace in der using Direktive weglassen, kurz:

namespace Outer
{
    using Inner;

    class Bar
    {
        public Foo foo;
    }
}




xml xpath namespaces xml-namespaces