Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding specific node in xml document with namespace in C#

I've tried many answers in Stackoverflow for solving my problem like this one. But none seems to work on my XML document.

This is my XML

<w:wordDocument xmlns:aml="http://schemas.microsoft.com/aml/2001/core" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:ve="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml" xmlns:wx="http://schemas.microsoft.com/office/word/2003/auxHint" xmlns:wsp="http://schemas.microsoft.com/office/word/2003/wordml/sp2" xmlns:sl="http://schemas.microsoft.com/schemaLibrary/2003/core"
  w:macrosPresent="no"
  w:embeddedObjPresent="no"
  w:ocxPresent="no"
  xml:space="preserve">
  <w:ignoreSubtree
    w:val="http://schemas.microsoft.com/office/word/2003/wordml/sp2" />
  ...
  <w:body>
    <w:p
      wsp:rsidR="009D1011"
      wsp:rsidRDefault="001D7CCD">
      ...

I'm trying to find <w:p> node which has namespace.

This is my latest try:

string xmlNamespace = String.Empty;
XmlNamespaceManager nsmgr;
//xml is my XMLDocument
XmlNodeList nodeInfo = xml.GetElementsByTagName("w:wordDocument");
XmlAttributeCollection att = nodeInfo[0].Attributes;
xmlNamespace = Convert.ToString(nodeInfo[0].Attributes["xmlns"].Value);
nsmgr = new XmlNamespaceManager(xml.NameTable);
nsmgr.AddNamespace("w", xmlNamespace);
XmlNode myNode = xml.DocumentElement.SelectSingleNode("w:wordDocument/w:body", nsmgr);

But myNode always returns null

Can anyone tell me what I'm doing wrong?

like image 345
Alex Jolig Avatar asked Aug 25 '26 09:08

Alex Jolig


1 Answers

Issues with your code:

  • to get namespace that used for given prefix (w in this case) you should either check proper xmlns:w attribute (not default xmlns, nor some random one like xmlns:alm) or in most cases simply specify explicitly - as it will never change in case of valid WordML documents for example.
  • to select elements staring from the root you either need to use XPath searching from the root ( /w:....) or perform select on node that have root element as child (document itself).

Possible variants of working code:

xmlNamespace = Convert.ToString(nodeInfo[0].Attributes["xmlns:w"].Value);
nsmgr = new XmlNamespaceManager(xml.NameTable);
nsmgr.AddNamespace("w", xmlNamespace);
XmlNode myNode = xml.SelectSingleNode("w:wordDocument/w:body", nsmgr);

or

nsmgr = new XmlNamespaceManager(xml.NameTable);
nsmgr.AddNamespace("w", "http://schemas.microsoft.com/office/word/2003/wordml");
XmlNode myNode = xml.DocumentElement
    .SelectSingleNode("/w:wordDocument/w:body", nsmgr);

or flat out ignore namespaces with local-name() function:

XmlNode myNode = xml.SelectSingleNode(
    "/*[local-name()='wordDocument']/*[local-name()='body']", nsmgr);
like image 166
Alexei Levenkov Avatar answered Aug 27 '26 00:08

Alexei Levenkov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!