Reputation: 12935
I have an xml string saved in a legacy database that I'm attempting to parse. I can get the string but having 2 issues getting the values that I need. First, some sample xml.
<?xml version="1.0" encoding="utf-16"?>
<email>
<meta>
<smartForm>
<unit name="ForgotUsername" label="Forgot Username Email">
<textBox name="FromEmail" label="From Email" type="Email" />
<textBox name="FromName" label="From Name" type="100" />
<textBox name="BccEmail" label="BCC" type="EmailList" />
<textBox name="Subject" label="Subject" type="300" />
<textBox2 name="TextBody" label="Body" type="Memo" />
</unit>
<unit name="ForgotPassword" label="Forgot Password Email">
<textBox name="FromEmail" label="From Email" type="Email" />
<textBox name="FromName" label="From Name" type="100" />
<textBox name="BccEmail" label="BCC" type="EmailList" />
<textBox name="Subject" label="Subject" type="300" />
<textBox2 name="TextBody" label="Body" type="Memo" />
</unit>
</smartForm>
</meta>
<value><?xml version="1.0" encoding="utf-16"?><root><ForgotPassword BccEmail="[email protected]" FromEmail="[email protected]" FromName="password test" Subject="password test" TextBody="info" /><ForgotUsername BccEmail="[email protected]" FromEmail="[email protected]" FromName="test" Subject="test" TextBody="test" /></root></value>
</email>
Issue #1 - I attempted to parse the xml using XElement.Parse("string")
however, I cannot get the <value>
node unless I remove the xml declaration (i.e. first 39 characters). I'm hoping to not HAVE to do this since it's a brittle solution.
Issue #2 - Once I have the <value>
element's contents and parsed into an XElement, I want the query to either the <ForgotUsername>
or <ForgotPassword>
child node of the <root>
document element. When I got .Elements()
, I'm told the collection is null.
What am I doing wrong?
The Value's XML after entities are replaced:
<root>
<ForgotPassword BccEmail="[email protected]" FromEmail="[email protected]" FromName="password test" Subject="password test" TextBody="info" />
<ForgotUsername BccEmail="[email protected]" FromEmail="[email protected]" FromName="test" Subject="test" TextBody="test" />
</root>
UPDATES: After trying abatishchev's initial suggestion - I changed the code for issue #1 to the following:
var xdoc = XDocument.Parse(contentXml);
return (from element in xdoc.Elements("value")
select element.Value).FirstOrDefault();
Based on the information provided, it should return the string in the value node; however, it's returning null. The xdoc.Elements() (or as shown in the above snippet) return null.
Upvotes: 2
Views: 2555
Reputation: 11945
For #1:
XElement doc = XElement.Load(file);
XElement valueElement = doc.Element("value");
string value = (string)valueElement;
Upvotes: 0
Reputation: 100238
XDocument.Parse()
to create a document supporting XML declarationTo get units, use
XDocument.Parse("...").Root // or Element("email")
.Elements("meta")
.Elements("smartForm")
.Elements("unit");
or use XPath: email/meta/smartForm/unit
also you can use query-style:
var doc = XDocument.Parse("...");
var q = from meta in doc.Root.Elements("meta")
from smartForm in meta.Elements("smartForm")
from unit in smartForm.Elements("unit")
select unit;
Upvotes: 2
Reputation: 77500
The following works for me:
var xd = XDocument.Load("Test.xml");
var xv = XDocument.Parse((string)xd.Root.Element("value"));
Console.WriteLine(xv.Root.Elements().Count());
Output is 2, for ForgotPassword and ForgotUsername.
Upvotes: 1