Philip Colmer
Philip Colmer

Reputation: 1674

XDocument isn't returning any values

I'm reading in some XML from a file. In the file, the XML is stored as one single line of text, like this:

<ArrayOfKeyValueOfstringanyType xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays"><KeyValueOfstringanyType><Key>askforreview</Key><Value xmlns:d3p1="http://www.w3.org/2001/XMLSchema" i:type="d3p1:boolean">false</Value></KeyValueOfstringanyType><KeyValueOfstringanyType><Key>started</Key><Value xmlns:d3p1="http://www.w3.org/2001/XMLSchema" i:type="d3p1:int">1</Value></KeyValueOfstringanyType><KeyValueOfstringanyType><Key>LastRunVersion</Key><Value xmlns:d3p1="http://www.w3.org/2001/XMLSchema" i:type="d3p1:int">148</Value></KeyValueOfstringanyType> ... etc

I'm reading the file in with a StreamReader, calling XDocument.Load. With the code in debugging, if I dump the variable that is the XDocument, Visual Studio prints out the XML in a formatted manner, suggesting that XDocument has properly parsed the single line of text:

<ArrayOfKeyValueOfstringanyType xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
  <KeyValueOfstringanyType>
    <Key>askforreview</Key>
    <Value xmlns:d3p1="http://www.w3.org/2001/XMLSchema" i:type="d3p1:boolean">false</Value>
  </KeyValueOfstringanyType>
  <KeyValueOfstringanyType>
    <Key>started</Key>
    <Value xmlns:d3p1="http://www.w3.org/2001/XMLSchema" i:type="d3p1:int">1</Value>
  </KeyValueOfstringanyType>
  <KeyValueOfstringanyType>
    <Key>LastRunVersion</Key>
    <Value xmlns:d3p1="http://www.w3.org/2001/XMLSchema" i:type="d3p1:int">148</Value>
  </KeyValueOfstringanyType>

etc

However, attempts to pull out elements, descendants, values, etc pretty much all result in null being returned. My concern is that if I call .Root, I again get all of the XML displayed, along with this:

FirstAttribute: {xmlns:i="http://www.w3.org/2001/XMLSchema-instance"}
HasAttributes: true
HasElements: true
IsEmpty: false
LastAttribute: {xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays"}
Name: {{http://schemas.microsoft.com/2003/10/Serialization/Arrays}ArrayOfKeyValueOfstringanyType}
NodeType: Element
Value: "askforreviewfalsestarted1LastRunVersion148 ... etc"

In other words, it looks like all of the values have been run together?

Update: clarity of what I've been trying to do ...

Given the suggestion about namespaces, I've tried this:

oldSettings = XDocument.Load(sr);
XNamespace f ="http://schemas.microsoft.com/2003/10/Serialization/Arrays";
XElement f1 = oldSettings.Element(f + "KeyValueOfstringanyType");

(Please excuse the var names - this is just in the Immediate Window)

That returns f1 as null. If I try:

f1 = oldSettings.Element(f + "ArrayOfKeyValueOfstringanyType");

then f1 is set to the whole of the XML document since that is the root element. Calling f1.Descendants() gives me nothing again.

Am I referencing the correct namespace? ArrayOfKeyValueOfstringanyType seems to have two - the one I've used above, plus the one that starts 'xmlns:i="https://...'.

If I try:

var f2 = oldSettings.Elements(f + "KeyValueOfstringanyType");

or

var f2 = oldSettings.Descendants(f + "KeyValueOfstringanyType");

or

var f2 = oldSettings.Root.Descendants(f + "KeyValueOfstringanyType");

I get null.

Following the example given in http://msdn.microsoft.com/en-us/library/bb669152.aspx, I've also tried this:

XNamespace xns = "http://schemas.microsoft.com/2003/10/Serialization/Arrays";
IEnumerable<XElement> kv = from el in oldSettings.Elements(xns + "KeyValueOfstringanyType")
                           select el;
var f4 = kv.ToList();

and f4 is also null.

What do I need to do in order to get this working? Do I need to reformat the XML to introduce new line characters? (The file isn't being created by me)

Thanks.

Upvotes: 1

Views: 394

Answers (2)

Martin Liversage
Martin Liversage

Reputation: 106916

You are simply making some simple mistakes:

XElement f1 = oldSettings.Element(f + "KeyValueOfstringanyType");

should be changed into

XElement f1 = oldSettings.Root.Element(f + "KeyValueOfstringanyType");

because you are looking for elements below the root element.

var f2 = oldSettings.Descendants(f + "KeyValueOfstringanyType");

will return the expected elements and not null so surely you must have som spelling mistake somewhere in your code.

Upvotes: 1

har07
har07

Reputation: 89325

Looking at those codes you've tried, seems that you're just unlucky :p The element you're trying to access is direct child of root element, so this one will get the desired element :

XElement f1 = oldSettings.Root.Element(f + "KeyValueOfstringanyType");

In case of using Descendant you need to call ToList() or ToArray(), or iterate through the result to see the actual content :

var f2 = oldSettings.Descendants(f + "KeyValueOfstringanyType").ToList();

Question similar to your problem when using Descendants() : C# XML Node Works with Element But Not with Elelments

Upvotes: 1

Related Questions