Tuesday, September 18, 2007

Parsing Xml with a Default Namespace Defined


What's that namespace doing there?


I recently answered a question on MS newsgroups regarding navigating an XML document whose fragment is below:
<?xml version="1.0" encoding="UTF-8"?>
<JMF xmlns="http://www.CIP4.org/JDFSchema_1_1" Version="1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Response ID="RDFS1934507113653e9" ReturnCode="0" Type="QueueStatus"
refID="132413dj323s223" xsi:type="ResponseQueueStatus">
<Queue DeviceID="Dev01" QueueSize="8" Status="Waiting">
<QueueEntry DeviceID="vl-5001" JobID="1048655" JobPartID="79">



The author of the question wanted to get to the QueueEntry using the following XPath expression:
JMF/Response/Queue/QueueEntry
Unfortunately - it returned no XmlNodes (when used in xmlDoc.SelectNodes(...)).

And here's why:
<JMF xmlns="http://www.CIP4.org/JDFSchema_1_1" ...
This means that all children of the <JMF> are in the "http://www.CIP4.org/JDFSchema_1_1" namespace.
So if you try to reference them without specifying that namespace, you are actually trying to reference some nodes that do not exist in the document!

Here's what you have to do to be able to select those nodes:
XmlDocument xmlDoc = new XmlDocument(); 
xmlDoc.LoadXml(doc);

XmlNamespaceManager nm = new
XmlNamespaceManager(xmlDoc.NameTable);
nm.AddNamespace("my", "http://www.CIP4.org/JDFSchema_1_1");

XmlNodeList list =
xmlDoc.SelectNodes("/my:JMF/my:Response/my:Queue/my:QueueEntry", nm);
foreach (XmlNode node in list)
{
string sID = node.Attributes["DeviceID"].Value;
}
Yeah, it looks a little bit cumbersome, but it works! :)

No comments: