Reputation: 1674
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
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
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