locked
How to get the attribut value when it has the colon in xml? RRS feed

  • Question

  • Hi all,

    I met a question that I can't get the attribute in the xml when the colon exists. For example, I want to get the value but it seems not working with my code. Any suggestions?

    XNamespace nameSpace=XNamespace.Get("http://www.w3.org/1999/xhtml");

    var info = from node in doc.Elements("stuff").Elements()
                    where node.Name.ToString().Equals("myFood")
                    select node.Attribute(XName.Get("Name", nameSpace.ToString()));

    XML:

    <myFood>
        <content:Foo content:name="Food" >
         <content:Foo content:name="Fruit" />   
        </my:Foo>
    </myFood>

    Thanks

    Wednesday, August 6, 2014 4:15 PM

Answers

  • The XML fragment you gave isn't valid.  content is a namespace prefix.  The namespace has to be defined otherwise the XML is not valid.  Additionally you have a Foo that is never ended and a my:Foo that never started.  It also appears that you have an element nested within itself which is uncommon for XML. 

    The actual name of the element includes the prefix.  When working with XML that includes namespaces you have to define the namespace-prefix mapping as well using XmlNamespaceManager. 

    There are a variety of ways of actually registering the namespace depending upon whether you're trying to support a generic XML file or a well defined XML file.  For a well defined XML file you can simply add the namespace prefix mapping yourself.

    If I modify your XML to be valid then I can get elements using this syntax.

    var xml = @"<?xml version=""1.0"" encoding=""utf - 8"" ?>
                <myFood xmlns:content = ""http://www.tempuri.org"">
                    <content:Foo content:name = ""Food"">
                        <content:Foo content:name = ""Fruit"" />
                    </content:Foo>
                    </myFood >";
    
    var doc = XDocument.Parse(xml);            
    
    var foods = doc.Descendants("myFood");
    
    var fooName = XName.Get("Foo", "http://www.tempuri.org");
    var foos = doc.Descendants(fooName);

    The key here is that the name you search for must include the namespace.  For generic XML where you don't know the namespace information then you have to write code to get the namespace given the prefix.  At that point though you're unlikely using XPath to get specific elements so it isn't much of an issue anyway.

    Michael Taylor
    http://blogs.msmvps.com/p3net

    • Proposed as answer by Ioana Vasilescu Thursday, August 7, 2014 8:25 AM
    • Marked as answer by Caillen Monday, August 18, 2014 3:10 AM
    Wednesday, August 6, 2014 6:14 PM

All replies

  • The XML fragment you gave isn't valid.  content is a namespace prefix.  The namespace has to be defined otherwise the XML is not valid.  Additionally you have a Foo that is never ended and a my:Foo that never started.  It also appears that you have an element nested within itself which is uncommon for XML. 

    The actual name of the element includes the prefix.  When working with XML that includes namespaces you have to define the namespace-prefix mapping as well using XmlNamespaceManager. 

    There are a variety of ways of actually registering the namespace depending upon whether you're trying to support a generic XML file or a well defined XML file.  For a well defined XML file you can simply add the namespace prefix mapping yourself.

    If I modify your XML to be valid then I can get elements using this syntax.

    var xml = @"<?xml version=""1.0"" encoding=""utf - 8"" ?>
                <myFood xmlns:content = ""http://www.tempuri.org"">
                    <content:Foo content:name = ""Food"">
                        <content:Foo content:name = ""Fruit"" />
                    </content:Foo>
                    </myFood >";
    
    var doc = XDocument.Parse(xml);            
    
    var foods = doc.Descendants("myFood");
    
    var fooName = XName.Get("Foo", "http://www.tempuri.org");
    var foos = doc.Descendants(fooName);

    The key here is that the name you search for must include the namespace.  For generic XML where you don't know the namespace information then you have to write code to get the namespace given the prefix.  At that point though you're unlikely using XPath to get specific elements so it isn't much of an issue anyway.

    Michael Taylor
    http://blogs.msmvps.com/p3net

    • Proposed as answer by Ioana Vasilescu Thursday, August 7, 2014 8:25 AM
    • Marked as answer by Caillen Monday, August 18, 2014 3:10 AM
    Wednesday, August 6, 2014 6:14 PM
  • Hi,

    It appears that the namespace in your xml is not properly declared. Please open the xml file in an xml editor or Visual Studio to see if any errors in the xml content. If you correct the namespaces in your xml, you can get the value.

    Also take a look at the following link.

    Can Linq to XML work with colons?




    Microsoft MVP - ASP/ASP.NET

    Wednesday, August 6, 2014 6:15 PM