Read from xml files with or without a namespace using XmlDocument
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
...
You could consider the following options:
- determine whether document contains namespace and depending on it construct xpath query
- use namespace agnostic xpath such as
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;
}
}