Solved

What is wrong with my attempt to read an xml file using xPath expressions (C#)

Posted on 2014-10-21
9
231 Views
Last Modified: 2014-10-22
I am trying to use this code to get to the Order elements in an xml file:

                    IEnumerable<XElement> nodeList = xDoc.XPathSelectElements("//Orders/Order");

I have used this technique before but can't find what I'm doing wrong on this particular one:

The xml file looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<Orders xmlns="http://www.junk.com/xml/mp/order/R1.1" xmlns:xsi="http://junk/2001/XMLSchema-instance" xsi:schemaLocation="http://www.junk.com/xml/mp/order/R1.1 http://support.junk.com/mp/R1.1/order/Orders.xsd">
    <Order>
        <OrderID>100000009</OrderID>
            (and all sorts of child elements)
    </Order>
    <Order>
        <OrderID>1000000111</OrderID>
            (and all sorts of child elements)
    </Order>
</Orders>
0
Comment
Question by:g_johnson
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 4
9 Comments
 
LVL 4

Author Comment

by:g_johnson
ID: 40395473
I found that this technique works if I strip out everything and the element looks like this:
<Orders>

I then can read it like this:  xDoc.XPathSelectElements("/Order");

However, in reality I can't strip that out.

How do I get around this?

Thanks,
0
 
LVL 34

Expert Comment

by:it_saige
ID: 40395710
Try this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
using System.Xml.XPath;

static class XmlExample
{
	public static void Main()
	{
		XmlReader reader = XmlReader.Create("Orders.xml");
		XElement data = XElement.Load(reader);
		XmlNameTable table = reader.NameTable;
		XmlNamespaceManager manager = new XmlNamespaceManager(table);
		manager.AddNamespace("ns", "http://www.junk.com/xml/mp/order/R1.1");
		foreach (XElement order in data.XPathSelectElements("./ns:Order", manager))
		{
			foreach (var pair in (from id in order.Elements() where id.Name.LocalName.Contains("OrderID") select new { id.Name.LocalName, id.Value }))
				Console.WriteLine(string.Format("Name - {0}; Value - {1}", pair.LocalName, pair.Value));
		}
		Console.ReadLine();
	}
}

Open in new window

Orders.xml:
<?xml version="1.0" encoding="UTF-8"?>
<Orders xmlns="http://www.junk.com/xml/mp/order/R1.1" xmlns:xsi="http://junk/2001/XMLSchema-instance" xsi:schemaLocation="http://www.junk.com/xml/mp/order/R1.1 http://support.junk.com/mp/R1.1/order/Orders.xsd">
	<Order>
		<OrderID>100000009</OrderID>
	</Order>
	<Order>
		<OrderID>1000000111</OrderID>
	</Order>
</Orders>

Open in new window

Produces the following output:Capture.JPG
-saige-
0
 
LVL 4

Author Comment

by:g_johnson
ID: 40397343
I can certainly try this, but I'm wondering why the xPath technique does not work if there is a namespace in the element.
0
Salesforce Made Easy to Use

On-screen guidance at the moment of need enables you & your employees to focus on the core, you can now boost your adoption rates swiftly and simply with one easy tool.

 
LVL 34

Expert Comment

by:it_saige
ID: 40397451
If you compare the Node Name between the Namespace version and non-Namespace version, you will find that when you declare a namespace that the Node Name is equal to the {Namespace} + XML Element Name; e.g. -Capture.JPGVersus the non-Namespace version, where the Node Name is equal to the XML Element Name; e.g. -Capture.JPG
-saige-
0
 
LVL 4

Author Comment

by:g_johnson
ID: 40397744
Thanks.  I understand that now, I think.

I combined that info with some other stuff I found in my research, and now this code runs without error but doesn't identify the nodes:

                    XDocument xDoc = XDocument.Load(XMLFileName);

                    XmlNamespaceManager oManager = new XmlNamespaceManager(new NameTable());
                    oManager.AddNamespace("ns", "{http://www.junk.com/xml/mp/order/R1.1}");
                    IEnumerable<XElement> nodeList = xDoc.XPathSelectElements("/ns:Orders/ns:Order",oManager);

Does this have anything to do with it having multiple namespaces in the Orders element?  Or is there something else I'm doing wrong?
0
 
LVL 34

Expert Comment

by:it_saige
ID: 40397918
Remove the brackets from around your namespace definition.

-saige-
0
 
LVL 34

Accepted Solution

by:
it_saige earned 500 total points
ID: 40397950
In other words; this line -
oManager.AddNamespace("ns", "{http://www.junk.com/xml/mp/order/R1.1}");

Open in new window

Should be entered this way -
oManager.AddNamespace("ns", "http://www.junk.com/xml/mp/order/R1.1");

Open in new window


-saige-
0
 
LVL 34

Expert Comment

by:it_saige
ID: 40397966
Making your modifications to the above code -
using System;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
using System.Xml.XPath;

static class XmlExample
{
	public static void Main()
	{
		XDocument document = XDocument.Load("Orders.xml");
		XmlNamespaceManager manager = new XmlNamespaceManager(new NameTable());
		manager.AddNamespace("ns", "http://www.junk.com/xml/mp/order/R1.1");

		foreach (XElement order in document.XPathSelectElements("/ns:Orders/ns:Order", manager))
		{
			foreach (var pair in (from id in order.Elements() where id.Name.LocalName.Contains("OrderID") select new { id.Name.LocalName, id.Value }))
				Console.WriteLine(string.Format("Name - {0}; Value - {1}", pair.LocalName, pair.Value));
		} 
		Console.ReadLine();
	}
}

Open in new window

Produces the following output -Capture.JPG
-saige-
0
 
LVL 4

Author Closing Comment

by:g_johnson
ID: 40398029
Thank you.  You've been very helpful!
0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Entity Framework is a powerful tool to help you interact with the DataBase but still doesn't help much when we have a Stored Procedure that returns more than one resultset. The solution takes some of out-of-the-box thinking; read on!
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
NetCrunch network monitor is a highly extensive platform for network monitoring and alert generation. In this video you'll see a live demo of NetCrunch with most notable features explained in a walk-through manner. You'll also get to know the philos…
Monitoring a network: why having a policy is the best policy? Michael Kulchisky, MCSE, MCSA, MCP, VTSP, VSP, CCSP outlines the enormous benefits of having a policy-based approach when monitoring medium and large networks. Software utilized in this v…

624 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question