Can't access XML with Linq
I am trying to parse the following XML file and nothing I do results in anything but the root or the firstnode.
<?xml version="1.0" encoding="utf-8" ?>
<Report {attributes}>
<table1>
<Detail_Collection>
<Detail {attributes} />
<Detail {a开发者_Python百科ttributes} />
<Detail {attributes} />
</Detail_Collection>
</table1>
</Report>
I am trying to get a list of Detail so that I can get the attribute values, but everything I have tried results in no data. My latest attempt is this one...
var xml= XDocument.Load(FileDetails.FullName);
var xml1 = XDocument.Parse(xml.Root.FirstNode.ToString());
var xml3 = from e in custs.Root.Elements("Detail") select e;
var xml4 = from e in xml1.Elements("Detail") select e;
Different attempt
var xml = XDocument.Load(FileDetails.FullName);
var root = xml.Root;
var els = root.Descendants("Detail");
The above displays in the immediate window:
root.Descendants("Detail") {System.Xml.Linq.XContainer.GetDescendants} name: null self: false System.Collections.Generic.IEnumerator.Current: null System.Collections.IEnumerator.Current: null
The problem is with the attributes in the Report element:
<Report p1:schemaLocation="Info_x0020_Tickets_x0020_Entered http://domain/ReportServer?%2fInfo+Reporting%2fInfo+Tickets+Entered&rs%3aCommand=Render&rs%3aFormat=XML&rs%3aSessionID=vcvb0p452bb3na45havjes55&rc%3aSchema=True" Name="Info Tickets Entered" textbox9="1247" xmlns:p1="http://www.w3.org/2001/XMLSchema-instance" xmlns="Info_x0020_Tickets_x0020_Entered">
This is from SQL Server Reporting Server, I'll have to remove one by one and find the culprit.
This is the final solution to this problem There may be a better way, but once the data is loaded you cannot easily remove the namespace.
//load the original document
var xml = XDocument.Load(FileDetails.FullName);
//remove all the superflouos data attributes
xml.Root.RemoveAttributes();
//turn into a string
var content = xml.Root.ToString();
//remove the official namespace, there is no easy way to remove the namespace after document has been loaded, so we'll replace it
var newXmlContent = content.Replace("<Report xmlns=\"Info_x0020_Tickets_x0020_Entered\">", "<Report>");
//parse the updated string into a workable document
var newXml = XDocument.Parse(newXmlContent).Root;
This returns a new XML document that can be processed normally.
Calling custs.Root.Elements("Detail")
will return all <Detail>
elements that are direct children of the root (<Report>
) element.
You need to call Descendants
.
Alternatively, you can call
custs.Root.Element("table1").Element("Detail_Collection").Elements("Detail")
EDIT: Your elements are probably in a namespace (xmlns="..."
in the root).
You need to ask XLINQ for the elements in the correct namespace:
XNamespace ns = "Info_x0020_Tickets_x0020_Entered";
var els = root.Descendants(ns + "Detail");
var xml= XDocument.Load(FileDetails.FullName);
var detailList = xml.Root.Decendants("Detail");
This will give you an enumerable collection of XElements
that are all the Detail
elements in the XML.
string xml = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
<Report foo=""bar"">
<table1>
<Detail_Collection>
<Detail foo=""bar"" />
<Detail foo=""bar"" />
<Detail foo=""bar"" />
</Detail_Collection>
</table1>
</Report>";
var doc = XDocument.Parse(xml);
foreach (var desc in doc.Root.Descendants("Detail"))
{
Console.WriteLine(desc.Attribute("foo").Value);
}
精彩评论