Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / XML / August 2007

Tip: Looking for answers? Try searching our database.

XPath and namespaces

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
David Thielen - 26 Aug 2007 22:18 GMT
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.

Signature

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

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

Martin Honnen - 27 Aug 2007 11:53 GMT
>     private void SetNamespace(XPathNavigator nav)
>     {
[quoted text clipped - 10 lines]
>                 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());
[quoted text clipped - 14 lines]
>           <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.

Signature

    Martin Honnen --- MVP XML
    http://JavaScript.FAQTs.com/

David Thielen - 27 Aug 2007 16:26 GMT
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?

Signature

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

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

> >     private void SetNamespace(XPathNavigator nav)
> >     {
[quoted text clipped - 45 lines]
> You do not say what exactly does not work. I assume the problem is
> simply the default namespace declaration on Customer.
Martin Honnen - 27 Aug 2007 16:48 GMT
> 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.

Signature

    Martin Honnen --- MVP XML
    http://JavaScript.FAQTs.com/

David Thielen - 27 Aug 2007 18:30 GMT
Ok, I think that makes sense to me.

Signature

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

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

> > I think the problem is two issues:
> >
[quoted text clipped - 39 lines]
> pose a problem in general if you have namespace declarations at various
> levels of the XML.

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.