XPath and namespaces

Hi;

First off, I think I still do not understand exactly how we are supposed to 
handle namespaces when doing xpath queries under .NET so I may have some bad 
assumptions here.

As I understand it, we need to set the namespaces on an XmlDocument - the 
..NET libraries do not read it from the xmlns:... attributes in the xml.

In our case we have to handle xml our customers will pass to our library so 
we do not know up front what namespaces will be in there or how they are set 
up. So we do the following:

	private void SetNamespace(XPathNavigator nav)
	{

		XPathNodeIterator list = nav.Select("//namespace::*[name() != 
'xml'][not(../../namespace::*=.)]");
		while (list.MoveNext())
		{
			XPathNavigator nsNode = list.get_Current();
			if (nsNode.get_NodeType() == XPathNodeType.Namespace)
			{
				if (context == null)
					context = new XmlNamespaceManager(nav.get_NameTable());
				if (nsNode.get_LocalName().equals(""))
					context.AddNamespace(String.Empty, nsNode.get_Value());
				else
					context.AddNamespace(nsNode.get_LocalName(), nsNode.get_Value());
			}
		}
	}

But this appears to not work for xml in the form:
<DaType Version="60.46.0.306">
  <DaCustomer>
    <Customer xmlns:i="http://www.w3.org/2001/XMLSchema-instance" 
xmlns="http://ibs.entriq.net/Customers">
      <BirthDate>0001-01-01T00:00:00</BirthDate>
      <BusinessUnitId>0</BusinessUnitId>
      <ClassId>1</ClassId>
      <CustomFields xmlns:d2p1="http://ibs.entriq.net/Core">
        <d2p1:CustomFieldValue>
          <d2p1:Extended i:nil="true" />
....

I assume because the d2p1 namespace applies to only part of the xml.

How should we handle this - especially as a single xpath can reference nodes 
both inside CustomFields and outside it sp on a single xpath d2p1 has meaning 
on some nodes and no meaning on others.

-- 
thanks - dave
david_at_windward_dot_net
http://www.windwardreports.com

Cubicle Wars - http://www.windwardreports.com/film.htm


0
thielen (152)
8/26/2007 9:18:01 PM
dotnet.xml 7266 articles. 0 followers. Follow

4 Replies
732 Views

Similar Articles

[PageSpeed] 14

David Thielen wrote:

> 	private void SetNamespace(XPathNavigator nav)
> 	{
> 
> 		XPathNodeIterator list = nav.Select("//namespace::*[name() != 
> 'xml'][not(../../namespace::*=.)]");
> 		while (list.MoveNext())
> 		{
> 			XPathNavigator nsNode = list.get_Current();
> 			if (nsNode.get_NodeType() == XPathNodeType.Namespace)
> 			{
> 				if (context == null)
> 					context = new XmlNamespaceManager(nav.get_NameTable());
> 				if (nsNode.get_LocalName().equals(""))
> 					context.AddNamespace(String.Empty, nsNode.get_Value());

The "problem" with XPath 1.0 is that you need a prefixed name to select 
elements in a namespace thus even if the input XML has a default 
namespace declaration in the form
   <element xmlns="http://example.com/2007/ns">
then for XPath to select elements in that namespace you need to bind a 
prefix to that namespace URI.
In the case of a default namespace declaration there is no prefix in the 
input XML so your user or your application has to choose a prefix and 
call AddNamespace with that prefix as the first argument. Then that 
prefix has to be used in XPath expressions.
Doing context.AddNamespace(String.Empty, ...) does not help for XPath 
evaluation.

> 				else
> 					context.AddNamespace(nsNode.get_LocalName(), nsNode.get_Value());
> 			}
> 		}
> 	}
> 
> But this appears to not work for xml in the form:
> <DaType Version="60.46.0.306">
>   <DaCustomer>
>     <Customer xmlns:i="http://www.w3.org/2001/XMLSchema-instance" 
> xmlns="http://ibs.entriq.net/Customers">
>       <BirthDate>0001-01-01T00:00:00</BirthDate>
>       <BusinessUnitId>0</BusinessUnitId>
>       <ClassId>1</ClassId>
>       <CustomFields xmlns:d2p1="http://ibs.entriq.net/Core">
>         <d2p1:CustomFieldValue>
>           <d2p1:Extended i:nil="true" />
> ...

You do not say what exactly does not work. I assume the problem is 
simply the default namespace declaration on Customer.





-- 

	Martin Honnen --- MVP XML
	http://JavaScript.FAQTs.com/
0
mahotrash (1778)
8/27/2007 10:53:40 AM
I think the problem is two issues:

1) There is no default namespace set. I understand the issue if there is a 
default namespace and a name has to be assigned to it. But what of this case 
where there is no default?

2) The namespace on the Customer element only applies to sub-elements of 
Customer - correct? But if I pass that as a namespace for the entire DOM then 
wouldn't that be incorrect?

-- 
thanks - dave
david_at_windward_dot_net
http://www.windwardreports.com

Cubicle Wars - http://www.windwardreports.com/film.htm




"Martin Honnen" wrote:

> David Thielen wrote:
> 
> > 	private void SetNamespace(XPathNavigator nav)
> > 	{
> > 
> > 		XPathNodeIterator list = nav.Select("//namespace::*[name() != 
> > 'xml'][not(../../namespace::*=.)]");
> > 		while (list.MoveNext())
> > 		{
> > 			XPathNavigator nsNode = list.get_Current();
> > 			if (nsNode.get_NodeType() == XPathNodeType.Namespace)
> > 			{
> > 				if (context == null)
> > 					context = new XmlNamespaceManager(nav.get_NameTable());
> > 				if (nsNode.get_LocalName().equals(""))
> > 					context.AddNamespace(String.Empty, nsNode.get_Value());
> 
> The "problem" with XPath 1.0 is that you need a prefixed name to select 
> elements in a namespace thus even if the input XML has a default 
> namespace declaration in the form
>    <element xmlns="http://example.com/2007/ns">
> then for XPath to select elements in that namespace you need to bind a 
> prefix to that namespace URI.
> In the case of a default namespace declaration there is no prefix in the 
> input XML so your user or your application has to choose a prefix and 
> call AddNamespace with that prefix as the first argument. Then that 
> prefix has to be used in XPath expressions.
> Doing context.AddNamespace(String.Empty, ...) does not help for XPath 
> evaluation.
> 
> > 				else
> > 					context.AddNamespace(nsNode.get_LocalName(), nsNode.get_Value());
> > 			}
> > 		}
> > 	}
> > 
> > But this appears to not work for xml in the form:
> > <DaType Version="60.46.0.306">
> >   <DaCustomer>
> >     <Customer xmlns:i="http://www.w3.org/2001/XMLSchema-instance" 
> > xmlns="http://ibs.entriq.net/Customers">
> >       <BirthDate>0001-01-01T00:00:00</BirthDate>
> >       <BusinessUnitId>0</BusinessUnitId>
> >       <ClassId>1</ClassId>
> >       <CustomFields xmlns:d2p1="http://ibs.entriq.net/Core">
> >         <d2p1:CustomFieldValue>
> >           <d2p1:Extended i:nil="true" />
> > ...
> 
> You do not say what exactly does not work. I assume the problem is 
> simply the default namespace declaration on Customer.
> 
> 
> 
> 
> 
> -- 
> 
> 	Martin Honnen --- MVP XML
> 	http://JavaScript.FAQTs.com/
> 
0
thielen (152)
8/27/2007 3:26:02 PM
David Thielen wrote:
> I think the problem is two issues:
> 
> 1) There is no default namespace set. I understand the issue if there is a 
> default namespace and a name has to be assigned to it. But what of this case 
> where there is no default?

You posted

<DaType Version="60.46.0.306">
   <DaCustomer>
     <Customer xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://ibs.entriq.net/Customers">

so there _is_ a default namespace declaration on Customer.

> 2) The namespace on the Customer element only applies to sub-elements of 
> Customer - correct? But if I pass that as a namespace for the entire DOM then 
> wouldn't that be incorrect?

If you are using an XmlNamespaceManager then you are simply managing 
your XML namespace for the purpose of XPath evaluation. Obviously if 
Customer is not the root element but has a default namespace declaration 
then that applies only to Customer and its descendants (where xmlns is 
not redefined). But for the purpose of the XmlNamespaceManager you need 
to bind prefixes for all namespaces of elements you want to select.
Thus if you do
   xmlNamespaceManagerInstance.AddNamespace("ic", 
"http://ibs.entriq.net/Customers");
you are not hurting your XPath evaluation in general, you just need to 
make sure that you use that prefix ic on the elements you are looking 
for in that namespace so
   //ic:Customer
is fine or
   /DaType/DaCustomer/ic:Customer
is fine to select that Customer element
while
   /ic:DaType
would not select anything then.

So you will need to find a strategy to generate prefixes and use and 
apply them, but XmlNamespaceManager and its AddNamespace method do not 
pose a problem in general if you have namespace declarations at various 
levels of the XML.


-- 

	Martin Honnen --- MVP XML
	http://JavaScript.FAQTs.com/
0
mahotrash (1778)
8/27/2007 3:48:46 PM
Ok, I think that makes sense to me.

-- 
thanks - dave
david_at_windward_dot_net
http://www.windwardreports.com

Cubicle Wars - http://www.windwardreports.com/film.htm




"Martin Honnen" wrote:

> David Thielen wrote:
> > I think the problem is two issues:
> > 
> > 1) There is no default namespace set. I understand the issue if there is a 
> > default namespace and a name has to be assigned to it. But what of this case 
> > where there is no default?
> 
> You posted
> 
> <DaType Version="60.46.0.306">
>    <DaCustomer>
>      <Customer xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
> xmlns="http://ibs.entriq.net/Customers">
> 
> so there _is_ a default namespace declaration on Customer.
> 
> > 2) The namespace on the Customer element only applies to sub-elements of 
> > Customer - correct? But if I pass that as a namespace for the entire DOM then 
> > wouldn't that be incorrect?
> 
> If you are using an XmlNamespaceManager then you are simply managing 
> your XML namespace for the purpose of XPath evaluation. Obviously if 
> Customer is not the root element but has a default namespace declaration 
> then that applies only to Customer and its descendants (where xmlns is 
> not redefined). But for the purpose of the XmlNamespaceManager you need 
> to bind prefixes for all namespaces of elements you want to select.
> Thus if you do
>    xmlNamespaceManagerInstance.AddNamespace("ic", 
> "http://ibs.entriq.net/Customers");
> you are not hurting your XPath evaluation in general, you just need to 
> make sure that you use that prefix ic on the elements you are looking 
> for in that namespace so
>    //ic:Customer
> is fine or
>    /DaType/DaCustomer/ic:Customer
> is fine to select that Customer element
> while
>    /ic:DaType
> would not select anything then.
> 
> So you will need to find a strategy to generate prefixes and use and 
> apply them, but XmlNamespaceManager and its AddNamespace method do not 
> pose a problem in general if you have namespace declarations at various 
> levels of the XML.
> 
> 
> -- 
> 
> 	Martin Honnen --- MVP XML
> 	http://JavaScript.FAQTs.com/
> 
0
thielen (152)
8/27/2007 5:30:01 PM
Reply:

Similar Artilces:

What is the best way to remove XML namespace
Hi, I am trying to remove the namespace in the root node in the following XML, <ordersHistory xmlns="http://tempuri.org/Orders.xsd"> <order number="PO-1" added="12/12/2002"> <client name="Microsoft"> <address country="USA" city="Washington" /> <notes> Produces a great framework for developing applications. </notes> </client> <items> <item id="1" name="Windows XP Professional" qty="2"...

XPath
Using XPath I am querying parts of XML document, " get quoted by \ - is it possible to specify not to quote " with \? <RootElement> <Element Attribute="SomeValue" /> </RootElement> XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(fileName); XmlNode xmlNode = xmlDoc.SelectSingleNode("//RootElement/Element") Print xmlNode.OuterXml <Element Attribute=\"SomeValue\"/> where I was expecting to get <Element Attribute="SomeValue"/> TIA Dennis wrote: > Using XPath I am querying parts of XML document,...

Getting a specific parent of any node via xpath navigation
I am storing my site structure as such: <menuItems> <menuItem> <pageID>1</pageID> </menuItem> <menuItem> <pageID>2</pageID> <menuItem> <pageID>4</pageID> <menuItem> <pageID>5</pageID> <menuItem> <pageID>6</pageID> </menuItem> </menuItem> </menuItem> </menuItem> <menuItem> <pageID>3</pageID> ...

XPath pb
Hi In infopath, I use a XPath expression to get some nodes : var oEMailNodeList = XDocument.DOM.selectNodes("//Message/EMail"); My problem is that this method returns 0 items. Here is the DOM.xml property : <?xml version="1.0" ?> <?mso-infoPathSolution productVersion=\"11.0.5329\" PIVersion=\"1.0.0.0\" href=\"file:///C:\Documents%20and%20Settings\t-stevbe\Local%20Settings\Appli cation%20Data\Microsoft\InfoPath\7ab6e8af39fc42e2\manifest.xsf\" solutionVersion=\"1.0.0.9\" initialView=\"messagesList\" ?> <?...

cannot load schema for the namespace
Hi, I am trying to validate an XML file using the XmlValidatingReader and XmlUrlResolver. The code for which goes like this: // Read the XML file. XmlTextReader xmlReader = new XmlTextReader( _PathToXMLDoc); XmlValidatingReader valReader = new XmlValidatingReader(xmlReader); valReader.ValidationType = ValidationType.Schema; XmlResolver xRes = new XmlUrlResolver(); valReader.XmlResolver = xRes; valReader.ValidationEventHandler += new ValidationEventHandler(this.ValidationCallBack); while(valReader.Read()) { } I have the XML document which refers to a xsd file located on a di...

How to pass a Nodeset to an XPath extension function?
I am using the .NET framework v2.0.40607 with Visual C# Express and I would like to create some custom XPath functions to use directly in a XSLT stylesheet. I called System.Xml.Query.XmlArgumentList.AddExtensionObject(string, object) to register the functions I've written. The functions that take a String, Boolean or Number parameter work perfectly. However, I do not know how to create a function that will accept a Nodeset as a parameter. I tried writting a function taking a XPathNavigator object, but it does not work for all XPath queries that return a Nodeset: I get an error &qu...

XPath Validation
I'm looking for a way to Validate an XPath prior to executing the expression, without using a try catch clause. For example: I'm looking for something that would tell me that "\some/Xpath\to\Node" is invalid... Any Ideas? Hi, As far as I know, the .NET framework could not validate XPath directly with class library. The only thing we can do is to use try/catch block. Or you can try to find some 3rd-party tool such as XML spy to validate it. HTH. Kevin Yu ======= "This posting is provided "AS IS" with no warranties, and confers no rights." Thanks K...

Xpath with namespaces
Hello Everyone, I am having an issue with xml and namespaces, at least I think it is namespaces. When I use namespaces, I cannot use SelectSingleNode / SelectNodes as they always return 0/Nothing respectively. Anyone have any thoughts? Thanks in advance VB.Net 2005 WinXP Sp2 Test code: Dim objXML As System.Xml.XmlDocument 'Test XML 1 ==> Always returns 0 objXML = New System.Xml.XmlDocument objXML.Load(Application.StartupPath & "\xmlfile1.xml") MsgBox(objXML.SelectNodes("top/middle").Count) 'Test XML 2 ==> Always re...

Tricky XPath query
Hi all, I've just changed the structure of my XML file and now I need to construct an XPathNavigator object that uses tags from two different levels in the XML file. For example: <someTag> <innerTagA> <innerInnerTagA> <innerInnerInnerTagA> Some Data That Belongs Here </innerInnerInnerTagA> <innerInnerInnerTagB> Some Data that Belongs More Specifically Here </innerInnerInnerTagB> </innerInnerTagA> <innerInnerTagB> <innerInnerInnerTagZ> This Data should real...

XML namespaces and XSD.exe
Oh boy i'm getting tangled in knots here. I have a schema which contains <xs:schema targetNamespace="http://Southend.Schemas.PAS/PASPatientDemographics.xsd" id="PASPatientDetails" xmlns:sh="http://Southend.Schemas.PAS/PASPatientDemographics.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"> now i used the xsd.exe and it now generates elements when I serilaize the class I get <RequestingPatient_ID xmlns="">D1234567890</RequestingPatient_ID> So each emlement contains xmlns=&qu...

xpath??
Hi, I am very new to xml. I have a datatable I need to group by and was suggested that xml and xpath might be the way to go. I converted the datatable to xml but don't know what to do next. Can anyone point me to the right direction. This is what I am trying to do: - have datatable (~300k rows and 5 cols) - need to group by column1(string catagory) and column2(date) - display the totals by column1 and column2 in datagrid. Any help is appreciated. Thanks. The advice to convert the database to XML was clearly a bad joke. RDBMSes are best at what they can do best -- work with relational da...

Sorting with XPATH
Given an XML node List with the individual nodes looking like the following, what kind of XPATH statement can I use to sort the nodes by element F8 and inside F8 by element F3? <OffNetworkRequestPackage> <Transaction> <OffNetworkRequest> <OffNetworkData> <UserEmail>loretta.pelisserok@getronics.com</UserEmail> <AdminEmail>NoEmail</AdminEmail> </OffNetworkData> <xxirequest> <function uuid="SBPProcess" name="CBICashCheck" bpname="TellerStd"/> </xxirequest> <TF&...

XPath and namespaces
Hi; First off, I think I still do not understand exactly how we are supposed to handle namespaces when doing xpath queries under .NET so I may have some bad assumptions here. As I understand it, we need to set the namespaces on an XmlDocument - the ..NET libraries do not read it from the xmlns:... attributes in the xml. In our case we have to handle xml our customers will pass to our library so we do not know up front what namespaces will be in there or how they are set up. So we do the following: private void SetNamespace(XPathNavigator nav) { XPathNodeIterator list = nav.Select...

XML namespaces and VB.Net
I posted this a few days ago and didn't get any response. I try again but ask it a little differently. I'm recieving any XML document from a client and I need to convert it to an ASCII delimited string to input into a legacy system. I've put together a VB.Net class that does this using DOM commands such as SelectSingleNode(). It works fine but I've noticed that it can not read past inbedded namespaces that are found throghout the document. I don't use namespaces in my own XML document so I do not know how to make this work or if I can. The system they are usi...

XPath with namespace
Hello all, I am working on an Add-in to the .NET framework using C#. I wanted to search the XML document using XPath but failed. The XML is like this: <unit xmlns="http://www.some.info/srcML" xmlns:cpp="http://www.some.info/srcML/cpp"> <aaa>something</aaa> </unit> The code I am using is as follows: XPathNavigator nav; XPathDocument docNav; XPathNodeIterator NodeIter; string fname="sth.xml"; docNav = new XPathDocument(@fname); nav = docNav.CreateNavigator(); nav.Evaluate(input); NodeIter = nav.Select(input); It works fine if there is n...

Tricky XPath query
Hey all, I've attempted to simplify my question (or at least the XML that is part of my example in my question): I have the following XML: <A> <B><C><D> I want to query the data in this node for the element B </D></C><E> I also want to query the data in this node for the element B </E> </B> <B><!--Additional data for another B element--> </B> </A> My idea is to do something like this: --------------------------------------------------- Dim nav As XPathNavigator = doc.CreateNaviga...

What is the Xpath
Hello, Thanks for the response Oleg. Now I need to know few answers. How do I get the value of a node using the xpath. I want the value of the MessageID and ResultCode from secondxml. And using this I want to delete the Child Nodes in the firstxml document. I am using the fowllowing code but the ni.current.value has values of all nodes in the file. I am confused. XmlDocument doc = new XmlDocument(); doc.Load("Firstxml.xml") hDocument doc2 = new XPathDocument("second.xml"); XPathNavigator nav = doc2.CreateNavigator(); foreach (XmlNo...

XMLnodelist and XPATH Problem
I am having a problem selecting nodes using the XMLnodelist Selectnodes using XPATH when I use XML SPY is successfully queries but when is use VB.net it comes up with nothing. Here is my code Dim nodess As XmlNode nodess = myNode.SelectSingleNode("//Web[@Url= 'http://localhost']") If nodess Is Nothing Then SQLrw.Delete() End If nodess = Nothing The myNode Properites ------------------------------------------------------------------------------------------------ {System.Xml.XmlElement} [System.Xm...

XPath string
Hi, I want to get the node with text=”{123}”. 1/ The following statement works fine: XmlNode wksNode = parentNode.SelectSingleNode("child::wks[text()='{123}']"); 2/ When I try to use a variable for the value of text, it doesn’t work anymore: string str = "child::wks[text()='" + myText + "']"; XmlNode wksNode3 = parentNode.SelectSingleNode(str); What is wrong? The variable str is exactly the same like the string used within the function SelectSingleNode in case 1/ Thanks for help, Lubomir Lubomir wrote: > When I try to use a varia...

Get attributes from XmlSchema for specific Node referenced by Xpath
I have a XSD loaded into a XmlSchema class. I need to retrieve the attribut names for/under a specific node in this schema, and I have the full xpath for the node in the schema. How do I do this? I'm not sure I should use the XmlSchema class to load the XSD. Regards Paw ...

XPath and SQLXML
I have the following XSD created in VS.NET 2003: <?xml version="1.0" encoding="utf-8" ?> <xs:schema id="ReferralSchama" targetNamespace="http://test.org/Referral" elementFormDefault="unqualified" xmlns="http://test.org/Referral" xmlns:mstns="http://test.org/Referral" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> <xs:complexType name="ReferralType"> <xs:sequence> <xs:element name="nReferralId" msdata:...

Problem selecting a node with XPATH if attribute value contains backslashes
VB6, MSXML 3.2 installed: Q1. I am having a problem selecting nodes with XPATH expressions when an attribute values contain backslashes (\\) in as part of its value: For example the following statement fails to find a node (even though one exists in the XML) if the value of the LDAPServerURL attribute is \\LocalServer but works if the value is "LocalServer". Set xmlElement = _ xmlConfigFile.documentElement.selectSingleNode("Facility[@LDAPServerURL='" & <SomeValue> & "']") I assumed that anything inside the '' was treated as a li...

XPath #4
This is a multi-part message in MIME format. ------=_NextPart_000_0016_01C44593.E9775F00 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Hi, I am new to XPath and I am stuck with an expression. I would like to = select all servers which the user subscribed to. Here is my XML: <forums> <forum> <name>AAA</name> <subscribed>1</subscribed> </forum> <forum> <name>BBB</name> <subscribed>0</subscribed> ...

xpath syntax
I have the following xml: <?xml version="1.0" ?> <course> <globalProperties> <externalMetadata> <source>ADL</source> <model>ADL SCORM 1.0</model> </externalMetadata> </globalProperties> <block id="B1"> <identification> <title>Yes/No Questions</title> <description>This course has one lesson</description> <labels> <curricular>MODULE</curricular> <developer>Me</developer> </labels> </identification&g...

XPath resource
hi, i've started working on xml but its location-path subject is too confusing. any good reference on web or book ? thanks ...