Search code examples
c#xmloffice-interop

Reading the xml below shows error in c#


<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  <w:document xmlns:ve="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml">
    <w:body>
      <w:customXml w:uri="Sample" w:element="note">
        <w:p w:rsidR="00B06944" w:rsidRDefault="0051608D" w:rsidP="000E0B9F">
          <w:customXml w:element="to">
            <w:r w:rsidR="000E0B9F" w:rsidRPr="00B84BAE">
              <w:rPr>
                <w:b/>
                <w:bCs/>
              </w:rPr>
              <w:t xml:space="preserve">Saran </w:t>
            </w:r>
          </w:customXml>
        </w:body>
     </w:document>

as I want to read the node < w:r > for this i am writing the below code

XmlDocument doc = new XmlDocument();
doc.Load("\\document.xml");
XmlNamespaceManager namespaceManager = new XmlNamespaceManager(doc.NameTable);
XmlNode node = doc.SelectSingleNode("/w:body/w:customXml/w:r", namespaceManager);

which gives:

The error shown in this line is Namespace Manager or XsltContext needed. This query has a prefix, variable, or user-defined function.

How can I read the Xml


Solution

  • You need to tell namespaceManager about the meaning of the alias w. It sounds like this is redundant (from the file), but it is not the case that the aliases you want for query are necessarily those from the source, since the meaning of the file is identical if I replace all the w aliases in the source document with foo (as long as I also define foo:xmlns to the be same). Or I could use xmlns instead of aliases throughout.

    Hence:

    XmlNamespaceManager namespaceManager = new XmlNamespaceManager(doc.NameTable);
    namespaceManager.Add("w",
        "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
    XmlNode node = doc.SelectSingleNode("/w:body/w:customXml/w:r", namespaceManager);
    

    This allows your query to succeed identically, regardless of the specific aliases used in the source.