none
XMLNS breaks XPath referencing

    Question

  •  

    I have the following XML:
    <configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
    <appSettings>
    <add key="Main.ConnectionString" value="foo">
    </appSettings>
    </configuration>

    The following XPath works 'only' when the above xmlns reference is removed:
    //configuration/appSettings/add[@key='Main.ConnectionString']/@value

     

    Unfortunately, because the application be changed in order to be compatible with the deployment solution, i need to find a way of using the above XPath reference with the xmlns reference as shown above. Is there a Namespace Manager in MSBuild?

    Any work arounds to this problem?

    Martynwb

    Tuesday, October 09, 2007 10:49 AM

Answers

  • > It would help, but I'm not doing this in C#, I'm doing it inb MSBuild. Is there anyway to
    > accomplish the same task without coding it? I'm using the namespace prefix, do I have to
    > place a prefix in the config file to match?

     

    This is a different question, butit still has the same answer:

     

    The following XPath expression will select the wanted nodes:

     

    //*[name() = 'configuration']/*[name()='appSettings']

               /*[name()='add'][@key='Main.ConnectionString']/@value

     

     

     

    Cheers,

    Dimitre Novatchev

     

    Tuesday, October 09, 2007 3:14 PM
  • If you want to select elements in that namespace then you need to bind a prefix to the namespace and use an XmlNamespaceManager e.g. C#

    Code Block

    XmlDocument xmlDoc = new XmlDocument();

    xmlDoc.Load("file.xml");

    XmlNamespaceManager nm = new XmlNamespaceManager(xmlDoc.NameTable);

    nm.AddNamespace("nf", "http://schemas.microsoft.com/.NetConfiguration/v2.0");

    XmlNode node = xmlDoc.SelectSingleNode("nf:configuration/nf:appSettings/nf:add[@key = 'Main.ConnectionString']/@value", nm);

     

     

     

    Tuesday, October 09, 2007 1:02 PM
  • This is one of the most FAQ in xml-related forums.

     

    As by spec, XPath considers unprefixed names to be in "no namespace". As your names are all in the "http://schemas.microsoft.com/.NetConfiguration/v2.0" namespace, the XPath expression:

     

        //configuration/appSettings/add[@key='Main.ConnectionString']/@value

     

    will not select any nodes.

     

    Read more about this here and here.

     

    There is a XmlNamespaceManager class in .NET that you can use to associate a prefix to your namespace.

     

    Then,  you can evaluate the following XPath expression:

     

        //mp:configuration/mp:appSettings/mp:add[@key='Main.ConnectionString']/@value

     

    A quick workaround is the following:

     

    //*[name() = 'configuration']/*[name()='appSettings']

               /*[name()='add'][@key='Main.ConnectionString']/@value

     

     

    Hope this helped.

     

    Cheers,

    Dimitre Novatchev

    Tuesday, October 09, 2007 1:05 PM
  • Are you using a custom build task? This page http://geekswithblogs.net/paulwhitblog/archive/2006/04/11/74844.aspx seems to talk about such a task and using it to manipulate .NET config files.

    Tuesday, October 09, 2007 2:51 PM

All replies

  • If you want to select elements in that namespace then you need to bind a prefix to the namespace and use an XmlNamespaceManager e.g. C#

    Code Block

    XmlDocument xmlDoc = new XmlDocument();

    xmlDoc.Load("file.xml");

    XmlNamespaceManager nm = new XmlNamespaceManager(xmlDoc.NameTable);

    nm.AddNamespace("nf", "http://schemas.microsoft.com/.NetConfiguration/v2.0");

    XmlNode node = xmlDoc.SelectSingleNode("nf:configuration/nf:appSettings/nf:add[@key = 'Main.ConnectionString']/@value", nm);

     

     

     

    Tuesday, October 09, 2007 1:02 PM
  • This is one of the most FAQ in xml-related forums.

     

    As by spec, XPath considers unprefixed names to be in "no namespace". As your names are all in the "http://schemas.microsoft.com/.NetConfiguration/v2.0" namespace, the XPath expression:

     

        //configuration/appSettings/add[@key='Main.ConnectionString']/@value

     

    will not select any nodes.

     

    Read more about this here and here.

     

    There is a XmlNamespaceManager class in .NET that you can use to associate a prefix to your namespace.

     

    Then,  you can evaluate the following XPath expression:

     

        //mp:configuration/mp:appSettings/mp:add[@key='Main.ConnectionString']/@value

     

    A quick workaround is the following:

     

    //*[name() = 'configuration']/*[name()='appSettings']

               /*[name()='add'][@key='Main.ConnectionString']/@value

     

     

    Hope this helped.

     

    Cheers,

    Dimitre Novatchev

    Tuesday, October 09, 2007 1:05 PM
  •  

    Thanks Guys,

     

     

    It would help, but I'm not doing this in C#, I'm doing it inb MSBuild. Is there anyway to accomplish the same task without coding it? I'm using the namespace prefix, do I have to place a prefix in the config file to match?

     

    Thanks again

     

    Martyn

    Tuesday, October 09, 2007 1:10 PM
  • The prefix is bound to a namespace URI (using AddNamespace) and that namespace URI matters, it needs to be the one defined in the XML document. The XML document does not need to be changed at all, the prefix is used in XPath expressions, not in the document.

    I am not familiar with MSBuild and XPath so I currently don't know how to solve the problem with MSBuild.

    Tuesday, October 09, 2007 1:22 PM
  • Thanks Martin,

     

    Does anybody have any experience with MSBuild in this context?

     

    Thanks

     

    Tuesday, October 09, 2007 2:34 PM
  • Are you using a custom build task? This page http://geekswithblogs.net/paulwhitblog/archive/2006/04/11/74844.aspx seems to talk about such a task and using it to manipulate .NET config files.

    Tuesday, October 09, 2007 2:51 PM
  • That seems to have done the trick. It was the prefix n, then using that prefix before each element in the XPath. many thanks!

     

     

    Martyn

    Tuesday, October 09, 2007 3:13 PM
  • > It would help, but I'm not doing this in C#, I'm doing it inb MSBuild. Is there anyway to
    > accomplish the same task without coding it? I'm using the namespace prefix, do I have to
    > place a prefix in the config file to match?

     

    This is a different question, butit still has the same answer:

     

    The following XPath expression will select the wanted nodes:

     

    //*[name() = 'configuration']/*[name()='appSettings']

               /*[name()='add'][@key='Main.ConnectionString']/@value

     

     

     

    Cheers,

    Dimitre Novatchev

     

    Tuesday, October 09, 2007 3:14 PM
  • Hi

    I am having the same problem. I have a xml doc with xmlns attribute in root element. I am using XSLT to parse this xml doc. So the XSLT works if the xmlns attribute is removed from the xml. Please help.

    Thanks,
    Lavanya
    Friday, February 13, 2009 10:40 PM
  • If you have e.g.
    <root xmlns="http://example.com/2009/ns1"
      <foo> 
        <bar>foobar</bar> 
      </foo> 
    </root> 

    then in your XSLT stylesheet you need to bind a prefix to the namespace URI and use that prefix in XPath expressions and match patterns:

    <xsl:stylesheet 
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
      xmlns:pf1="http://example.com/2009/ns1" 
      version="1.0"
     
      <xsl:template match="pf1:root"
        <xsl:value-of select="pf1:foo/pf1:bar"/> 
      </xsl:template> 
     
    </xsl:stylesheet> 


    MVP XML
    • Proposed as answer by John Saunders Saturday, February 14, 2009 1:14 PM
    Saturday, February 14, 2009 12:42 PM