I have some code that reads from xml files with a namespace using XmlDocument.My challenge is that i have the namespace of the file i'm reading hard coded for now and i pass that to the XmlNamespaceManager.I would like for my approach to be a little more flexible.To read from any kind of xml file.If it has a namespace,then use the namespace manager to read the elements without hard coding the namespace.If the file doesn't have a namespace,then go ahead and just parse it.Below is what I've done.
xmldoc = new XmlDocument ();
xmldoc.Load (fileLocation);
XmlNamespaceManager nameSpaceManager = new XmlNamespaceManager(xmldoc.NameTable);
nameSpaceManager.AddNamespace ("ns","http://schemas.sample.data.org/2005");
XmlNodeList nodeList = xmldoc.SelectNodes("/ns:Demo/ns:Items",  nameSpaceManager);
if (nodeList != null) 
{
    foreach (XmlNode childNode in nodeList) 
    {
        string first = childNode.SelectSingleNode ("ns:First", nameSpaceManager).InnerText;
        string second= childNode.SelectSingleNode ("ns:Second", nameSpaceManager).InnerText;
        string third = childNode.SelectSingleNode ("ns:Third", nameSpaceManager).InnerText;
    }
}
Here's the sample xml file i'm using
<Demo xmlns:i="http://www.justasample.com" xmlns="http://schemas.sample.data.org/2005">
 <Items>
  <First>first</First>
  <Second>second</Second>
  <Third>third</Third>
  </Items>
</Demo>
                You could consider the following options:
local-name(), which will
ignore the namespace
Option 1
var xmlDoc = new XmlDocument();
xmlDoc.Load(fileLocation);
//determine  whether document contains namespace
var namespaceName = "ns";
var namespacePrefix = string.Empty;
XmlNamespaceManager nameSpaceManager = null;
if (xmlDoc.FirstChild.Attributes != null)
{
    var xmlns = xmlDoc.FirstChild.Attributes["xmlns"];
    if (xmlns != null)
    {
          nameSpaceManager = new XmlNamespaceManager(xmlDoc.NameTable);
          nameSpaceManager.AddNamespace(namespaceName, xmlns.Value);
          namespacePrefix = namespaceName + ":";
    }
}
XmlNodeList nodeList = xmlDoc.SelectNodes(string.Format("/{0}Demo/{0}Items",namespacePrefix), nameSpaceManager);
if (nodeList != null)
{
    foreach (XmlNode childNode in nodeList)
    {
       string first = childNode.SelectSingleNode(namespacePrefix + "First", nameSpaceManager).InnerText;
       string second = childNode.SelectSingleNode(namespacePrefix + "Second", nameSpaceManager).InnerText;
       string third = childNode.SelectSingleNode(namespacePrefix +  "Third", nameSpaceManager).InnerText;
     }
 }
Option 2
XmlNodeList nodeList = xmlDoc.SelectNodes("/*[local-name() = 'Demo']/*[local-name() = 'Items']");
if (nodeList != null)
{
    foreach (XmlNode childNode in nodeList)
    {    
        string first = childNode.SelectSingleNode("*[local-name() = 'First']").InnerText;
        string second = childNode.SelectSingleNode("*[local-name() = 'Second']").InnerText;
        string third = childNode.SelectSingleNode("*[local-name() = 'Third']").InnerText;
     }
}
                        Improving Vadim's Option1, but using XDocument (instead of XmlDocument) API and F# instead of C#:
let fileStream = File.Open(fileLocation, FileMode.Open)
let xDocument = XDocument.Load fileStream
let nsOpt =
    let nsString = xDocument.Root.Name.Namespace.ToString()
    if String.IsNullOrEmpty nsString then
        Console.Error.WriteLine "Warning: no namespace URL found in xmlns attrib"
        None
    else
        let nsManager = XmlNamespaceManager(NameTable())
        let nsPrefix = "x"
        nsManager.AddNamespace(nsPrefix, nsString)
        if nsString <> "http://schemas.sample.data.org/2005" then
            Console.Error.WriteLine "Warning: the namespace URL doesn't match expectations, query may result in no elements"
        Some(nsManager, sprintf "%s:" nsPrefix)
let query = "//{0}Demo/{0}Items"
let nodes =
    match nsOpt with
    | None ->
        let fixedQuery = String.Format(query, String.Empty)
        xDocument.XPathSelectElements fixedQuery
    | Some(nsManager, nsPrefix) ->
        let fixedQuery = String.Format(query, nsPrefix)
        xDocument.XPathSelectElements(fixedQuery, nsManager)
for node in nodes do
    ...
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With