This question already has answers here:
How does one parse XML files? [closed]
(12 answers)
Closed 7 years ago.
I have an XML file that looks like:
<results>
<result>
<title>Welcome+to+The+JASON+Project%21</title>
<url>http%3A%2F%2Fwww.jason.org%2F</url>
<domain />
<inside_links>
<inside_link>
<description>News</description>
<url>http%3A%2F%2Fwww.jason.org%2FPublic%2FNews%2FNews.aspx</url>
</inside_link>
<inside_link>
<description>register</description>
<url>http%3A%2F%2Fwww.jason.org%2Fpublic%2Fregistration%2Fregistration.aspx</url>
</inside_link>
<inside_link>
<description>Argonauts</description>
<url>http%3A%2F%2Fwww.jason.org%2FPublic%2FArgonauts%2FArgonauts.aspx</url>
</inside_link>
<inside_link>
<description>Curriculum</description>
<url>http%3A%2F%2Fwww.jason.org%2FPublic%2FCurriculum%2FCurriculum.aspx</url>
</inside_link>
<inside_link>
<description>Credits</description>
<url>http%3A%2F%2Fwww.jason.org%2Fpublic%2FMisc%2FCredits.aspx</url>
</inside_link>
</inside_links>
<inside_keywords>National+Science+Education+Standards, National+Geographic+Society, Physical+Science, Professional+Development, Earth+Science</inside_keywords>
</result>
</results>
...And I'm very confused as to how to read it. I simply want to get the Title, Description, and URL into separate strings. Something like:
foreach line in lines
string title = gettitle;
string description = getdescription;
string url = geturl;
...I've read so many tutorials but all of them seem to not be relative to what i need to do.. Can somebody please help me out with this?
If you are using .NET 3.5, I'd suggest using LINQ to XML...
XDocument doc = XDocument.Load(filename);
XElement insideLinks = doc.Root.Element("result").Element("inside_links");
foreach (XElement insideLink in insideLinks.Elements())
{
string description = (string)insideLink.Element("description");
string url = (string)insideLink.Element("url");
}
This also lets you use the built-in "query" syntax so you could do something like this...
XDocument doc = XDocument.Load(filename);
XElement insideLinks = doc.Root.Element("result").Element("inside_links");
var allTitles = from XElement insideLink
in insideLinks.Elements("inside_link")
select (string)insideLink.Element("title");
(edited per comment)
To extend the LINQ to XML suggestion, you can use a select clause to create objects to represent the parsed links:
XDocument doc = XDocument.Load(filename);
var links = from link in doc.Descendants("inside_link")
select new
{
Description = (string)link.Element("description"),
Url = HttpUtility.UrlDecode((string)link.Element("url"))
};
foreach(var l in links)
Console.WriteLine("{1}", l.Url, l.Description);
In this case, links will be a sequence of objects that have an anonymous type with Description and Url properties, with Url decoded. This foreach would show something like this:
News
register
...
try this:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load("yourfile.xml");
foreach (XmlNode result in xmlDoc.SelectNodes("/results/result"))
{
string title = result.SelectSingleNode("title").InnerText;
string url = result.SelectSingleNode("url").InnerText;
foreach (XmlNode insideLink in result.SelectNodes("inside_links/inside_link"))
{
string description = insideLink.SelectSingleNode("description").InnerText;
}
}
Related
This question already has answers here:
Can't use Descendants() or Elements() with xmlns
(3 answers)
Closed 6 years ago.
I have following XML formatted string in string __MessageIn variable:
string _MessageIn=
<?Label TSRAY|RESERVATION|317859|SUCCESS?>
<Reservation xmlns="reservation.fidelio.2.0" mfShareAction="NA" mfReservationAction="EDIT">
<HotelReference>
<hotelCode>TSRAY</hotelCode>
</HotelReference>
<confirmationID>Y6Z7TFJDK</confirmationID>
<reservationID>347557</reservationID>
<reservationOriginatorCode>JA</reservationOriginatorCode>
<originalBookingDate>2010-08-16T22:53:23.000</originalBookingDate>
<StayDateRange timeUnitType="DAY">
<startTime>2010-08-19T00:00:00.000</startTime>
<numberOfTimeUnits>3</numberOfTimeUnits>
</StayDateRange>
<GuestCounts>
<GuestCount>
<ageQualifyingCode>ADULT</ageQualifyingCode>
<mfCount>2</mfCount>
</GuestCount>
<GuestCount>
<ageQualifyingCode>CHILD</ageQualifyingCode>
<mfCount>0</mfCount>
</GuestCount>
</GuestCounts>
...................
..................
</Reservation>
I'm trying to get the value of hotelcode i.e. TSRAY from <hotelCode>TSRAY</hotelCode> but the code always returns NULL In HotelReference.
I tried below lines of code:
// query the XML document
XDocument doc = XDocument.Parse(_MessageIn);
var HotelReference = doc.Descendants("HotelReference").Select(x => new { HotelCode = x.Element("hotelCode").Value}).FirstOrDefault();
How can I get the required value from above XML formatted string variable?
Thanks in Advance!
This is happening because of namespaces being part of the xml.
There are 2 ways to overcome this issue, either remove the namespace "reservation.fidelio.2.0" then your code will work without issues. But this might not be feasable.
So we'll have to pass the namespace along with the nodenames when performing searches.. try the following and this would solve your issue. Hope this helps.
string ns = "reservation.fidelio.2.0";
string node = "HotelReference";
string elem = "hotelCode";
XName xn = XName.Get(node, ns);
XName xe = XName.Get(elem, ns);
var HotelReference = doc.Root.Descendants(xn).Select(x => new { HotelCode = x.Element(xe).Value }).FirstOrDefault();
Try this,
string _MessageIn="<?Label TSRAY|RESERVATION|317859|SUCCESS?> <Reservation xmlns='reservation.fidelio.2.0' mfShareAction='NA' mfReservationAction='EDIT'> <HotelReference> <hotelCode>TSRAY</hotelCode> </HotelReference> <confirmationID>Y6Z7TFJDK</confirmationID> <reservationID>347557</reservationID> <reservationOriginatorCode>JA</reservationOriginatorCode> <originalBookingDate>2010-08-16T22:53:23.000</originalBookingDate> <StayDateRange timeUnitType='DAY'> <startTime>2010-08-19T00:00:00.000</startTime> <numberOfTimeUnits>3</numberOfTimeUnits> </StayDateRange> <GuestCounts> <GuestCount> <ageQualifyingCode>ADULT</ageQualifyingCode> <mfCount>2</mfCount> </GuestCount> <GuestCount> <ageQualifyingCode>CHILD</ageQualifyingCode> <mfCount>0</mfCount> </GuestCount> </GuestCounts> ................... .................. </Reservation>";
string HotelCode = ""; // you can create HotelCode-Array to store all Hotelcodes
XmlDocument doc = new XmlDocument();
doc.LoadXml(_MessageIn);
XmlNodeList list=doc.GetElementsByTagName("hotelCode");
foreach (XmlNode node in list)
{
if (node.Name == "hotelCode")
{
HotelCode=node.InnerText;
}
}
This question already has answers here:
Deserializing XML from String
(2 answers)
Closed 6 years ago.
I get this XML string for my web page, how can I retrieve data from that XML and assign values to labels in my web page?
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<things>
<bat>201400000586</bat>
<status>Y</status>
<totalAmount>3090</totalAmount>
<billno>P2355</billno>
<ReceiveDate>27/04/2015 06:22:18 PM</ReceiveDate>
</things>
Firstly load the Xml Doc using XMLDocument
XDocument doc = XDocument.Load(filePath);
XElement rootElm = doc.Element("things")
Now using linq you can fetch IENumerable
IEnumerable<XElement> childList = from Y in rootElm.Root.Elements()
select Y;
Now ou can loop through list items
foreach (XElement elm in childList)
{
//Here you can access elements this way
Console.log(elm.Element("status").Value);
..........
}
Here you can even edit the contents in xml file and save them.
Assign the values for the XElement type elements in the loop
doc.Save(filePath);
There are different ways to do this. Here is one.
You'll need to add "using System.Xml.XPath;"
XPathDocument doc = new XPathDocument(Server.MapPath("~/XMLFile1.xml"));
XPathNavigator nav = doc.CreateNavigator();
XPathExpression exp = nav.Compile(#"/things");
foreach (XPathNavigator item in nav.Select(exp))
{
label1.Text = item.SelectSingleNode("bat").ToString();
label2.Text = item.SelectSingleNode("totalAmount").ToString();
}
Or you can load it as a string, then use EITHER XmlElement or XmlNode with such a simple XML structure.
XmlDocument m_xml = new XmlDocument();
m_xml.LoadXml(#"<?xml version=""1.0"" encoding=""utf-8"" standalone=""yes"" ?><things><bat>201400000586</bat><status>Y</status><totalAmount>3090</totalAmount><billno>P2355</billno><ReceiveDate>27/04/2015 06:22:18 PM</ReceiveDate></things>");
XmlNode node_bat = m_xml.SelectSingleNode("//things/bat");
XmlNode node_totalAmount = m_xml.SelectSingleNode("//things/totalAmount");
XmlElement node_bat1 = m_xml.DocumentElement["bat"];
XmlElement node_totalAmount1 = m_xml.DocumentElement["totalAmount"];
label1.Text = node_bat1.InnerText;
label2.Text = node_totalAmount1.InnerText;
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why XDocument can’t get element out of this wellform XML text?
I'm trying to read an xml using linq to xml, and i guess i'm understanding something wrong.
This is the start of the xml (it's long so i'm not posting it all)
<?xml version="1.0" encoding="utf-8"?>
<Report xmlns="http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition" xmlns:rd="http://schemas.microsoft.com/SQLServer/reporting/reportdesigner">
<Body>
<ReportItems>
<Tablix Name="Tablix12">
......
......
</Tablix>
This xml could have a few of "Tablix" elements, and might have 1 or none, for each one of these i want to read whats inside this tag and i'm having difficulty to start.
I have tried a few ways to get the "Tablix" elements, or any other element.
In this code i get a result only for the "var root", the rest of them are always null and i don't understand what i'm doing wrong.
public ReadTablixResponse ReadTablixAdvanced(string rdl)
{
XDocument xml = XDocument.Parse(rdl);
var root = xml.Root;
var Body = xml.Root.Element("Body");
var report = xml.Root.Element("Report");
var aa = xml.Element("Report");
var bb = xml.Element("Body");
var test = xml.Elements("Tablix");
One thing i noticed, is that you used the method Element("name"). which will always try to retrun the first (in document order) direct child element with the specified XName . and that is probebly why you got null.
if you want to return deeper elements(from where you looking). you need to use the Descendants("name") method, which will return a collection of all descendants elements . no matter how deep they are (relative to your chosen anchor)...
for example:
XNamespace xNameSpace = "http://schemas.micro.....";
// ...
var tablixes= xml.Descendants(xNameSpace + "Tablix");
which you can then wolk through:
foreach (var tablix in tablixes)
{
var name=(string)tablix.Attribute("Name");
var age=(int)tablix.Element("age");
...
}
XDocument xDocument = XDocument.Parse(rdl);
XNamespace xNameSpace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition";
var tablixes= from o in xDocument.Descendants(xNameSpace + "Tablix")
select o.Value;
Considering the following XML:
<Stations>
<Station>
<Code>HT</Code>
<Type>123</Type>
<Names>
<Short>H'bosch</Short>
<Middle>Den Bosch</Middle>
<Long>'s-Hertogenbosch</Long>
</Names>
<Country>NL</Country>
</Station>
</Stations>
There are multiple nodes. I need the value of each node.
I've got the XML from a webpage (http://webservices.ns.nl/ns-api-stations-v2)
Login (--) Pass (--)
Currently i take the XML as a string and parse it to a XDocument.
var xml = XDocument.Parse(xmlString);
foreach (var e in xml.Elements("Long"))
{
var stationName = e.ToString();
}
You can retrieve "Station" nodes using XPath, then get each subsequent child node using more XPath. This example isn't using Linq, which it looks like you possibly are trying to do from your question, but here it is:
XmlDocument xml = new XmlDocument();
xml.Load(xmlStream);
XmlNodeList stations = xml.SelectNodes("//Station");
foreach (XmlNode station in stations)
{
var code = station.SelectSingleNode("Code").InnerXml;
var type = station.SelectSingleNode("Type").InnerXml;
var longName = station.SelectSingleNode("Names/Long").InnerXml;
var blah = "you should get the point by now";
}
NOTE: If your xmlStream variable is a String, rather than a Stream, use xml.LoadXml(xmlStream); for line 2, instead of xml.Load(xmlStream). If this is the case, I would also encourage you to name your variable to be more accurately descriptive of the object you're working with (aka. xmlString).
This will give you all the values of "Long" for every Station element.
var xml = XDocument.Parse(xmlStream);
var longStationNames = xml.Elements("Long").Select(e => e.Value);
In my previous question here, I didn’t understand how to solve my problem.
Linq to XML, how to acess an element in C#?
Here is my XML I need to parse:
<root>
<photo>/filesphoto.jpg</photo>
<photo:mtime>12</photo:mtime>
<text>some text</text>
</root>
To access the element I use this code:
var doc = XDocument.Parse(xml.Text);
doc.Descendants("text").FirstOrDefault().Value;
How can I access ?
I have try http://aspnetgotyou.blogspot.com/2010/06/xdocument-or-xelement-with-xmlnamespace.html,
But it is ignored <photo:mtime> and I need to access it.
Please write some code.
Contrary to #BrokenGlass' comments, your XML is not invalid. In fact the technique in the link you provided in your question (for loading namespaces) works fine. Maybe you just didn't change the example for your own needs. Here's a more compact generalization for parsing xml fragments with namespaces into an XElement:
public static XElement parseWithNamespaces(String xml, String[] namespaces) {
XmlNamespaceManager nameSpaceManager = new XmlNamespaceManager(new NameTable());
foreach (String ns in namespaces) { nameSpaceManager.AddNamespace(ns, ns); }
return XElement.Load(new XmlTextReader(xml, XmlNodeType.Element,
new XmlParserContext(null, nameSpaceManager, null, XmlSpace.None)));
}
Using your exact input:
string xml =
#"<root>
<photo>/filesphoto.jpg</photo>
<photo:mtime>12</photo:mtime>
<text>some text</text>
</root>";
XElement x = parseWithNamespaces(xml, new string[] { "photo" });
foreach (XElement e in x.Elements()) {
Console.WriteLine("{0} = {1}", e.Name, e.Value);
}
Console.WriteLine(x.Element("{photo}mtime").Value);
Prints:
photo = /filesphoto.jpg
{photo}mtime = 12
text = some text
12
Try this: (Your xml is changed a little, see )
string xml = "<root><photo>/filesphoto.jpg</photo><photoMtime>12</photoMtime><text>some text</text></root>";
var doc = XDocument.Parse(xml);
string value = doc.Descendants("text").FirstOrDefault().Value;
MessageBox.Show(value);