简体   繁体   中英

Get element using XName in XML

I have an XML file which looks like this, the call out is that namespace uses prefix, xmlns:opf .

<?xml version="1.0" encoding="utf-8"?>
<package version="2.0" unique-identifier="uuid_id" xmlns:opf="http://www.idpf.org/2007/opf">
    <metadata xmlns:dcterms="http://purl.org/dc/terms/">
    </metadata>
</package>

Following is my code trying to get the 'package' element using the XName

static void Main(string[] args)
{
    using (MemoryStream stream = new MemoryStream(File.ReadAllBytes(@"C:\Users\xyz\Downloads\XMLs\X2.xml")))
    {
        XDocument xDoc = XDocument.Load(stream);
        XNamespace opfNamespace = "http://www.idpf.org/2007/opf";

        XElement packageElement = xDoc.Element(opfNamespace + "package");

        Console.WriteLine($"packageElement is null - {packageElement == null}");
        Console.WriteLine($"Prefix - [{xDoc.Root.GetPrefixOfNamespace(opfNamespace)}] Namespace - [{xDoc.Root.GetNamespaceOfPrefix("opf")}]");

        foreach (var element in xDoc.Elements())
        {
            Console.WriteLine($"Element: Namespace - [{element.Name.NamespaceName}] Name - [{element.Name.LocalName}]");
        }
    }
}

The output of the program is -

packageElement is null - True
Prefix - [opf] Namespace - [http://www.idpf.org/2007/opf]
Element: Namespace - [] Name - [package]

So, it's not able to find the element using opfNamespace + "package" , for further debugging I logged the elements, and it shows that the element.Name does not contain the namespace, which explains why it's not able to find element using opfNamespace + "package" .

Question - How do I find the 'package' element from the above XML, I don't want to iterate through all the elements manually?

Is the XML parsing happening correctly, and the 'package' element not having namespace is expected?

For further testing, I removed the prefix from the namespace and ran the code, this time it's able to find the 'package' element.

XML -

<?xml version="1.0" encoding="utf-8"?>
<package version="2.0" unique-identifier="uuid_id" xmlns="http://www.idpf.org/2007/opf">
    <metadata xmlns:dcterms="http://purl.org/dc/terms/">
    </metadata>
</package>

Output -

packageElement is null - False
Prefix - [] Namespace - []
Element: Namespace - [http://www.idpf.org/2007/opf] Name - [package]

That package XML element is not defined in the http://www.idpf.org/2007/opf XML namespace.

That xmlns:opf="http://www.idpf.org/2007/opf" is just de definition of that namespace without being applied on the package XML element.

This means that it is to be retrieved as below

XElement packageElement = xDoc.Element("package");

If that package element would belong to that XML namespace, than it would be defined as

<opf:package version="2.0" unique-identifier="uuid_id" xmlns:opf="http://www.idpf.org/2007/opf">
    <!-- ... -->
</opf:package>

or

<package version="2.0" unique-identifier="uuid_id" xmlns="http://www.idpf.org/2007/opf">
    <!-- ... -->
<package>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM