3

I have this XML

<?xml version="1.0" encoding="UTF-8" ?>
<uclassify xmlns="http://api.uclassify.com/1/ResponseSchema" version="1.01">
  <status success="true" statusCode="2000"/>
  <readCalls>
    <classify id="cls1">
      <classification textCoverage="1">
        <class className="female" p="0.932408"/>
        <class className="male" p="0.0675915"/>
      </classification>
    </classify>
  </readCalls>
</uclassify>

or similar. What matters is, I don't have

<tag>value</tag> 

but

<tag attribute1 attribute2 ... />. 

What I want to output is for instance

attribute1: attributevalue1

So I want to enter a term like "female" and I want it to output 0.932408.

What I tried to get started

string xml = HttpGet("http://uclassify.com/browse/" + username + "/" + classifiername + "/" + operation + "?" + paramz.ToString());
XDocument doc = XDocument.Parse(xml);
var list = doc.Root.Elements("uclassify")
               .Select(element => element.Value)
               .ToList();

But list is always empty, which is presumably because there are no values, only attributes.

EDIT:

current version

string xml = HttpGet("http://uclassify.com/browse/" + username + "/" + classifiername + "/" + operation + "?" + paramz.ToString());
XDocument doc = XDocument.Parse(xml);
XNamespace ns = "http://api.uclassify.com/1/ResponseSchema";
var list = doc.Root.Descendants(ns + "class")
                .Select(element => element.Value)
                .ToList();
textBox1.Text = string.Join(",", list.ToArray());

Result is a comma.

  • 1
    System.Xml.Linq has a bit of an annoying way of handling `xmlns`, which you are not accounting for. Take a look at this question: http://stackoverflow.com/questions/4985974/xelement-namespaces-how-to – vcsjones Mar 19 '13 at 22:39

1 Answers1

4

SO your problem is the default namespace:

xmlns="http://api.uclassify.com/1/ResponseSchema"

To fix it, you need to qualify your element selector.

You can do this like so...

XNamespace ns = "http://api.uclassify.com/1/ResponseSchema";
var list = doc.Root.Descendants(ns + "class")
                .Select(element => element.Value)
                .ToList();

I've modified your code slightly to select all the class nodes, but you can see that I've prefaced your "class" in the Descendants() call with the namespace variable ns.

EDIT: So now your problem is that you are selecting the element's values, not the attributes values...

so if we are building a dictionary of attribute names to attribute values, you might want to use some code like this:

Dictionary<string,double> dictionary = doc.Root.Descendants(ns + "class")
                .ToDictionary(
                    element => element.Attribute("className").Value,
                    element => double.Parse(element.Attribute("p").Value));

foreach(var item in dictionary)
{
    Console.WriteLine(string.Format("{0}: {1}", item.Key, item.Value));
}

so a couple of caveats:

  1. I'm assuming that each of the className attributes in the class attributes are unique, otherwise you'll have an exception
  2. I'm assuming the value of the attribute p is a double.
Alastair Pitts
  • 19,423
  • 9
  • 68
  • 97