• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1398
  • Last Modified:

Reading xml node value from xpath usning c#, xml have many different namespaces

Hi,

I am working in Asp.net 2.0 using C# and reading xml from xpath query

I need to read Key and value inner text from my attached xml file

All key and Value node is at xpath in given xml file:


\\tcm:Component\tcm:Data\tcm:Content\Resources\Text

I am getting null values from my below code

// node.SelectSingleNode("Key", ns) this value is null
// node.SelectSingleNode("Key") is also coming null

therefore unable to read inner text, may be because of lot of namespaces.

Can you please help in this

Many Thanks ComponentTest.xml
private void getComponentResourceKeyValue(string xml)
        {
            try
            {
                XmlDocument doc = new XmlDocument();
                doc.LoadXml(xml);

                XmlNamespaceManager ns = new XmlNamespaceManager(doc.NameTable);
                ns.AddNamespace("tcm", "http://www.tridion.com/ContentManager/5.0");
                ns.AddNamespace("xlink", "http://www.w3.org/1999/xlink");
                ns.AddNamespace(string.Empty, "http://www.testcomp.com/tridion/schemas");

                XmlNodeList nodeList = doc.SelectNodes("//*[local-name()='Text']"); // This is giving me nodelist with no issues

                foreach (XmlNode node in nodeList)
                {
 			// node.SelectSingleNode("Key", ns) this value is null
			// node.SelectSingleNode("Key") is also coming null


                    string key = node.SelectSingleNode("Key", ns).InnerText;
                    string value = node.SelectSingleNode("Value", ns).InnerText;

                }
            }
            catch (Exception ex)
            {
                throw ex;
            }           
        }

Open in new window

0
tia_kamakshi
Asked:
tia_kamakshi
  • 5
  • 5
2 Solutions
 
nmarunCommented:
I was not able to meddle with the namespaces, but you can try something like this:

string key = node.ChildNodes[0].InnerText; // for Key element
string value = node.ChildNodes[1].InnerText; // for Value element

Thanks,
Arun
0
 
anarki_jimbelCommented:
Try the following (it works):
foreach (XmlNode node in nodeList)
            {
                XmlElement ele = (XmlElement)node;
                string key = ele.GetElementsByTagName("Key").Item(0).InnerText;
                string value = ele.GetElementsByTagName("Value").Item(0).InnerText;
            }

Open in new window

0
 
anarki_jimbelCommented:
About nmarun's solution.

I was thinking about it. But usually there is no guarantee in elements order...

So, if not guarantee - don't use...
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
nmarunCommented:
anarki_jimbel, seems like you were doing some vb.net before, your post has C# and vb.net code mixed up. The piece of code that'll work is:

ele.GetElementsByTagName("Key").Item[0].InnerText;

You are right about the order, so here's a fix for that.
foreach (XmlNode node in nodeList)
{
    string key = string.Empty;
    string value = string.Empty;
    for (int i = 0; i < node.ChildNodes.Count; i++)
    {
        switch (node.ChildNodes[i].Name)
        {
            case "Key":
                key = node.ChildNodes[i].InnerText;
                break;
            case "Value":
                value = node.ChildNodes[i].InnerText;
                break;
        }
    }

    Console.WriteLine("{0} - {1}", key, value);
}

Open in new window

0
 
nmarunCommented:
And as a last step, I found the correct xpath for the code that the author was trying.
XmlNodeList nodeList = doc.SelectNodes("//*[local-name()='Text']"); 
foreach (XmlNode node in nodeList)
{
    var key = node.SelectSingleNode("*[local-name()='Key']").InnerText;
    var value = node.SelectSingleNode("*[local-name()='Value']").InnerText;
    Console.WriteLine("{0} - {1}", key, value);
}

Open in new window

0
 
Sathish DVSoftware EngineerCommented:
Hi,

Its good it follow the solution given by mmarun. But if you still need more specifically from Namespacemanager(XmlDocument object is agnostic to Namespaces.  It believes Namespaces exist hence why XmlNode has a Namespace property but the XPath parsers do not by default know what namespaces are at play in the document) you can better follow this one.

Replace the below code
                    string key = node.SelectSingleNode("Key", ns).InnerText;
                    string value = node.SelectSingleNode("Value", ns).InnerText;

Open in new window

with
                    string key = node.SelectSingleNode("//*[local-name()='Key']", ns).InnerText;
                    string value = node.SelectSingleNode("//*[local-name()='Value']", ns).InnerText;

Open in new window

0
 
nmarunCommented:
sathishinfotech, The '//' is incorrect. It's basically telling the xpath to look from the root node every time and not from the current selected Text node. This will result in the InnerText of the first Key and Value nodes everytime.

Arun
0
 
anarki_jimbelCommented:
nmarun, try to run my code - no errors there. I use methods, not indexed properties!

Usually I post ONLY code I can run...
0
 
anarki_jimbelCommented:
About XmlNodeList.Item  METHOD:

http://msdn.microsoft.com/en-us/library/system.xml.xmlnodelist.item(v=VS.80).aspx

As a matter of fact, I can program freely in both C# and VB.
0
 
nmarunCommented:
anarki_jimbel, My bad, your code does work.
0
 
anarki_jimbelCommented:
Sorry, today's Monday - I'm grumpy... :)
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

  • 5
  • 5
Tackle projects and never again get stuck behind a technical roadblock.
Join Now