3

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?

Community
  • 1
  • 1
Ghasem
  • 14,455
  • 21
  • 138
  • 171
  • @AlexeiLevenkov i tried without `aml` as well. didn't work. – Ghasem Apr 08 '15 at 05:57
  • So even if you hardcode correct namespace like `nsmgr.AddNamespace("w", "http://schemas.microsoft.com/office/word/2003/wordml")` it does not work?? (I assume you understand meaning of `xmlns:..` attributes, otherwise your question should be completely different and possibly off-topic on SO) – Alexei Levenkov Apr 08 '15 at 06:00
  • @AlexeiLevenkov Tried that too. still the same. – Ghasem Apr 08 '15 at 06:03

1 Answers1

8

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);
Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179