XML Document Parsing C# - c#

I have a REST web service that creates a XMLDocument I am a bit confused on how access the inner text in FormattedPrice using XMLNode. I can grad offers but that will give me all the inner text.
<Offers>
<Offer>
<OfferListing>
<Price>
<Amount>1067</Amount>
<CurrencyCode>USD</CurrencyCode>
<FormattedPrice>$10.67</FormattedPrice>
</Price>
</OfferListing>
</Offer>
</Offers>

A quick walk-through of XPath will help immensely if you're using the Xml DOM.
This should meet your immediate need:
XmlNode n = doc.DocumentElement.SelectSingleNode("Offer/OfferListing/Price/FormattedPrice");
That will get you the first Offer's Formatted price (and assumes that your Offers node is the root). Other mechanisms exist in XPath that are a bit less brittle and that's where a tutorial would help you.

You are probably be best off using XPath.
XmlDocument doc = ...;
XmlNode fPrice;
XmlElement root = doc.DocumentElement;
fPrice= root.SelectSingleNode("/Price/FormattedPrice");
return fPrice.InnerText;
Here's a good example: http://www.codeproject.com/KB/cpp/myXPath.aspx

Use XElement to parse it:
string tmp = #"
<Offers>
<Offer>
<Price>
<Amount>1067</Amount>
<CurrencyCode>USD</CurrencyCode>
<FormattedPrice>$10.67</FormattedPrice>
</Price>
</Offer>
</Offers>";
XElement xml = XElement.Parse(tmp);
string formatedPrice = (string)xml.XPathSelectElement("/Offer/Price/FormattedPrice");

This should grab the $ amount:
var price = doc.SelectSingleNode(#"//Offer/Price/FormattedPrice");
string priceText = price.InnerText;

Load what you want into a XmlNodeList and then pull one explicitly or loop through them...
XmlNodeList pricesList = xmlDoc.GetElementsByTagName("FormattedPrice");
string firstPrice = pricesList[0].InnerText;

First off, your XML is invalid....you are missing the starting OfferListing tag.
Here is yet another option to grab the node text.
var xmlString = "<Offers><Offer><OfferListing><Price><Amount>1067</Amount<CurrencyCode>USD</CurrencyCode><FormattedPrice>$10.67</FormattedPrice></Price></OfferListing></Offer></Offers>";
var xDoc = new XmlDocument();
xDoc.LoadXml(xmlString);
var formattedPrice = xDoc.GetElementsByTagName("FormattedPrice")[0].InnerText;

Related

get contents from inner xml with xml parsing in c#?

I have a service which returns the below xml as string.I am using Xdocument parse method and XmlDocument load methods to convert the string to xml. but i want to parse and get the status and i_numer which i need to use for further processing.can some one point me in right direction or give some hints.below is the xml i am using.
i tried the innerxml property from the Xdocument and XmlDocument which is returning the whole "" element and this is not what i needed.
<Report>
<Incidentreport Company="company1" ID="sample">
<status i_number="12345678" status="sucessful" />
</Incidentreport>
</Report>
The following should work:
string str = [string of xml goes here];
string i_number = string.Empty;
XmlDocument doc = new XmlDocument();
doc.Load(str);
XmlNode node = doc.SelectSingleNode("//status");
i_number = node.Attributes["i_number"].Value;
You can use SelectSingleNode() which accept XPath parameter to get the target attribute value in one go * :
var raw = #"<Report>
<Incidentreport Company='company1' ID='sample'>
<status i_number='12345678' status='sucessful' />
</Incidentreport>
</Report>";
var doc = new XmlDocument();
doc.LoadXml(raw);
var result = doc.SelectSingleNode("/Report/Incidentreport/status/#i_number");
Console.WriteLine(result.Value);
dotnetfiddle demo
*) notice how XML attribute can be referenced by using #attribute_name syntax in XPath

Filter XMLNodeList using xPath & Wildcard characters

I have "XML" as below:
<ParentNode>
<ChildNode id="1" Display_Name="ABC"/>
<ChildNode id="2" Display_Name="DEF"/>
<ChildNode id="3" Display_Name="DAX"/>
<ChildNode id="4" Display_Name="LAM"/>
<ChildNode id="5" Display_Name="PKR"/>
<ChildNode id="6" Display_Name="UYA"/>
</ParentNode>
I want to get list of all the Nodes in XMLNodeList in C# using xPath having "A" [regardless of capitals or small] in Display_Name attribute.
What I've tried is:
root.SelectNodes("descendant-or-self::*[contains(#DISPLAY_NAME,'end')]")
Here, root is containing my XML and it is an object of XMLDocument.
Also, how can I make this filter by ignoring either Display_Name is in small letters or capital letters.
"I want to get list of all the Nodes in XMLNodeList in C# using xPath having "A" [regardless of capitals or small] in Display_Name attribute. "
Nature of XML and XPath is case-sensitive. There is no pretty way to do case-insensitive matching using XPath (at least in XPath 1.0, version that is supported by .NET). One known way is using translate() to convert Display_Name value to lower-case before doing further comparison, something like this (see related post) :
var xpath = #"//*[
contains(
translate(#Display_Name
,'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
,'abcdefghijklmnopqrstuvwxyz'
)
,'a'
)
]";
var result = root.SelectNodes(xpath);
Try with below XPath
/ParentNode/ChildNode/#Display_Name
To get result for both
Above XPath will return you all results of ChildNode. Now iterate this XPath to extract all results
Hope it will help you :)
Use OuterXml method.
Try this:
//Load Data
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xmlString);
//Go the xPath
XmlNode titleNode = xmlDoc.SelectSingleNode(xPath);
//Get the OutXml (You dont need to use a new variable)
string nodeValue = titleNode.OuterXml;
//Load this string as a new XmlDocument and use the second xPath
XmlDocument xmlDoc2 = new XmlDocument();
xmlDoc2.LoadXml(nodeValue);
titleNode = xmlDoc.SelectSingleNode(xPath2);

Parsing xml response - Select specific node based on value of another node

I'm new to xml so I'm not sure if I worded the question correctly, but I will do my best to explain.
Basically, I'm trying to parse an xml response in C# such as the one below:
<Premium>
<TotalPremiumAmount>87</TotalPremiumAmount>
<StandardPremium>87</StandardPremium>
<OptionalPremium>0</OptionalPremium>
<StandardTax>0</StandardTax>
<OptionalTax>0</OptionalTax>
<ExtendedTax>0</ExtendedTax>
<ExtendedPremium>0</ExtendedPremium>
<PromotionalPremium>0</PromotionalPremium>
<FeesPremium>0</FeesPremium>
<FeesTax>0</FeesTax>
<StandardFeesPremium>0</StandardFeesPremium>
<OptionalFeesPremium>0</OptionalFeesPremium>
<Tax>0</Tax>
<StandardPremiumDistribution>
<Travelers>
<Traveler>
<TravelerPremium>42</TravelerPremium>
<TravelerTax>0</TravelerTax>
</Traveler>
<Traveler>
<TravelerPremium>45</TravelerPremium>
<TravelerTax>0</TravelerTax>
</Traveler>
</Travelers>
</StandardPremiumDistribution>
<PackagePremiumDistribution>
<Packages>
<Package>
<PackageID>20265</PackageID>
<PackageName />
<PackageTypeID>12</PackageTypeID>
<Premium>87</Premium>
<Fees>0</Fees>
<Tax>0</Tax>
<Travelers>
<Traveler>
<TravelerID>0</TravelerID>
<Premium>42</Premium>
<Tax>0</Tax>
</Traveler>
<Traveler>
<TravelerID>1</TravelerID>
<Premium>45</Premium>
<Tax>0</Tax>
</Traveler>
</Travelers>
</Package>
</Packages>
</PackagePremiumDistribution>
</Premium>
I would like to get the value of the (Traveler) Premium. In the case of only one traveler, I have been using an XMLDocument and the 'SelectSingleNode" function. For example I could do something like:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(xmlResponse);
var premium = xmlDoc.SelectSingleNode("//TravelerPremium").InnerText;
But this wouldn't work when multiple travelers are returned under one plan. For example, I need the premium when TravelerID = 0. How would I go about doing this?
Thanks.
Using XmlDocument:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(xmlResponse);
var premium = xmlDoc.SelectSingleNode("//Premium[../TravelerID = '0']")
You could also iterate through the nodes if multiple could match on this condition like so:
foreach(var premium in xmldoc.SelectNodes("//Premium[../TravelerID = '0']")
{
// do work on each premium node where TravelerID = 0
}
I'd encourage you to look into using LINQ to XML - it's generally easier to work with and will be more performant in most cases. You could even still use XPath expressions, but the following would work:
XDocument xdoc = XDocument.Load(xmlResponse);
var premium = (string)xdoc.Descendants("Traveler").Where(x => (string)x.Element("TravelerID") == "0").Element("Premium");
Assuming your xml looks like that, try something like this:
XmlDocument doc = new XmlDocument();
xmlDoc.Load(xmlResponse);
if (doc.HasChildNodes)
{
foreach (XmlNode node in doc.DocumentElement.ChildNodes)
if (node.Name == "StandardPremiumDistribution")
{
XmlNodeList xnList = node.SelectNodes("//Travelers");
double travelerPremium= xnList.Item(z).FirstChild.InnerText);
}}
Based on this, I think you're gonna do it.
Let's suppose you have a file called XMLFile1.xml with the XML you posted you can iterate through all your TravelerPremium with the following code:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load("XMLFile1.xml");
XmlNodeList premiums = xmlDoc.SelectNodes("//TravelerPremium");
foreach(XmlNode node in premiums)
{
MessageBox.Show(node.FirstChild.InnerText);
}
You can also acces the other elements with similar code.

Get content of XML node using c#

simple question but I've been dinking around with it for an hour and it's really starting to frustrate me. I have XML that looks like this:
<TimelineInfo>
<PreTrialEd>Not Started</PreTrialEd>
<Ambassador>Problem</Ambassador>
<PsychEval>Completed</PsychEval>
</TimelineInfo>
And all I want to do is use C# to get the string stored between <Ambassador> and </Ambassador>.
So far I have:
XmlDocument doc = new XmlDocument();
doc.Load("C:\\test.xml");
XmlNode x = doc.SelectSingleNode("/TimelineInfo/Ambassador");
which selects the note just fine, now how in the world do I get the content in there?
May I suggest having a look at LINQ-to-XML (System.Xml.Linq)?
var doc = XDocument.Load("C:\\test.xml");
string result = (string)doc.Root.Element("Ambassador");
LINQ-to-XML is much more friendly than the Xml* classes (System.Xml).
Otherwise you should be able to get the value of the element by retrieving the InnerText property.
string result = x.InnerText;
The InnerText property should work fine for you.
http://msdn.microsoft.com/en-us/library/system.xml.xmlnode.innertext.aspx
FWIW, you might consider switching API to linq-to-xml (XElement and friends) as IMHO it's a friendly, easier API to interact with.
System.Xml version (NOTE: no casting to XmlElement needed)
var xml = #"<TimelineInfo>
<PreTrialEd>Not Started</PreTrialEd>
<Ambassador>Problem</Ambassador>
<PsychEval>Completed</PsychEval>
</TimelineInfo>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
var node = doc.SelectSingleNode("/TimelineInfo/Ambassador");
Console.WriteLine(node.InnerText);
linq-to-xml version:
var xml = #"<TimelineInfo>
<PreTrialEd>Not Started</PreTrialEd>
<Ambassador>Problem</Ambassador>
<PsychEval>Completed</PsychEval>
</TimelineInfo>";
var root = XElement.Parse(xml);
string ambassador = (string)root.Element("Ambassador");
Console.WriteLine(ambassador);
XmlDocument doc = new XmlDocument();
doc.Load("C:\\test.xml");
XmlNode x = doc.SelectSingleNode("/TimelineInfo/Ambassador");
x.InnerText will return the contents
Try using Linq to XML - it provides a very easy way to query xml datasources - http://msdn.microsoft.com/en-us/library/bb387098%28v=VS.100%29.aspx

Read attribute from xml

Can someone help me read attribute ows_AZPersonnummer with asp.net using c# from this xml structure
<listitems
xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882"
xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882"
xmlns:rs="urn:schemas-microsoft-com:rowset"
xmlns:z="#RowsetSchema"
xmlns="http://schemas.microsoft.com/sharepoint/soap/">
<rs:data ItemCount="1">
<z:row
ows_AZNamnUppdragsansvarig="Peter"
ows_AZTypAvUtbetalning="Arvode till privatperson"
ows_AZPersonnummer="196202081276"
ows_AZPlusgiro="5456436534"
ows_MetaInfo="1;#"
ows__ModerationStatus="0"
ows__Level="1" ows_ID="1"
ows_owshiddenversion="6"
ows_UniqueId="1;#{11E4AD4C-7931-46D8-80BB-7E482C605990}"
ows_FSObjType="1;#0"
ows_Created="2009-04-15T08:29:32Z"
ows_FileRef="1;#uppdragsavtal/Lists/Uppdragsavtal/1_.000"
/>
</rs:data>
</listitems>
And get value 196202081276.
Open this up in an XmlDocument object, then use the SelectNode function with the following XPath:
//*[local-name() = 'row']/#ows_AZPersonnummer
Basically, this looks for every element named "row", regardless of depth and namespace, and returns the ows_AZPersonnummer attribute of it. Should help avoid any namespace issues you might be having.
The XmlNamespaceManager is your friend:
string xml = "..."; //your xml here
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
XmlNamespaceManager nsm = new XmlNamespaceManager(new NameTable());
nsm.AddNamespace("z", "#RowsetSchema");
XmlNode n = doc.DocumentElement
.SelectSingleNode("//#ows_AZPersonnummer", nsm);
Console.WriteLine(n.Value);
You can also use LINQ to XML:
XDocument xd = XDocument.Parse(xml);
XNamespace xns = "#RowsetSchema";
string result1 = xd.Descendants(xns + "row")
.First()
.Attribute("ows_AZPersonnummer")
.Value;
// Or...
string result2 =
(from el in xd.Descendants(xns + "row")
select el).First().Attribute("ows_AZPersonnummer").Value;
I'd say you need an XML parser, which I believe are common. This looks like a simple XML structure, so the handling code shouldn't be too hard.
Use <%# Eval("path to attribute") %> but you need to load the xml has a DataSource.
Otherwise you can load it using XmlTextReader. Here's an example.

Categories