Read attribute from xml - c#

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.

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

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.

Linq-to-Xml prefix parse error

I am currently trying to learn how to parse data, and its a bit confusing. can someone check out my code and see what I'm doing wrong or if im even heading in the right direction.
XML File:
<xml xmlns:a='BLAH'
xmlns:b='BLAH'
xmlns:c='BLAH'
xmlns:d='BLAH'>
<a:info>
<b:cat Option1='blah' Option2='blah' Option3='blah' />
</a:info>
</xml>
C# Code:
XmlDocument doc = new XmlDocument();
doc.Load(richTextBox2.Text);
XmlNamespaceManager man = new XmlNamespaceManager(doc.NameTable);
man.AddNamespace("a", "BLAH");
man.AddNamespace("b", "BLAH");
man.AddNamespace("c", "BLAH");
man.AddNamespace("d", "BLAH");
XmlNode temps = doc.SelectSingleNode("/a:info/b:cat/Option1/", man);
richTextBox1.Text = temps.InnerText;
I am new to C#, I cant find a good example explaining how to successfully use loops to find more then one:
<b:chat />
You are using the wrong API if you're looking for LINQ to XML. Use the XDocument class instead.
Assume the following input XML-document (please note namespace URLs):
<xml xmlns:a='http://localhost/scheme_a'
xmlns:b='http://localhost/scheme_b'
xmlns:c='http://localhost/scheme_c'
xmlns:d='http://localhost/scheme_d'>
<a:info>
<b:cat Option1='1' Option2='1' Option3='1' />
</a:info>
<a:info>
<b:cat Option1='2' Option2='2' Option3='2' />
</a:info>
</xml>
There are the ways to get all <b:chat /> elements.
XmlDocument class:
var xmlDocument = new XmlDocument();
xmlDocument.Load(...);
var xmlNamespaceManager = new XmlNamespaceManager(xmlDocument.NameTable);
xmlNamespaceManager.AddNamespace("a", "http://localhost/scheme_a");
xmlNamespaceManager.AddNamespace("b", "http://localhost/scheme_b");
xmlNamespaceManager.AddNamespace("c", "http://localhost/scheme_c");
xmlNamespaceManager.AddNamespace("d", "http://localhost/scheme_d");
var bCatNodes = xmlDocument.SelectNodes("/xml/a:info/b:cat", xmlNamespaceManager);
var option1Attributes = bCatNodes.Cast<XmlNode>().Select(node => node.Attributes["Option1"]);
// Also, all Option1 attributes can be retrieved directly using XPath:
// var option1Attributes = xmlDocument.SelectNodes("/xml/a:info/b:cat/#Option1", xmlNamespaceManager).Cast<XmlAttribute>();
LINQ to XML XDocument Class. XName can be passed with a namespace to Descendants() and Element() methods.
Use Descendants() to get all <b:chat /> elements.
var xDocument = XDocument.Load(...);
XNamespace xNamespace = "http://localhost/scheme_b";
var xElements = xDocument.Descendants(xNamespace + "cat");
// For example, get all the values of Option1 attribute for the b:chat elements:
var options1 = xElements.Select(element => element.Attribute("Option1")).ToList();

Reading Elements within a Namespace

I have an XML file that looks like:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="https://www.someurl.com/somefile.xslt"?>
<AutoInsuranceClaim xmlns="http://www.someurl.com/schemas/AutoInsuranceClaim">
<Identification>
<BaseOwner>3</BaseOwner>
<BaseType>ABC123</BaseType>
<BaseTypeRef>471038341757</BaseTypeRef>
</Identification>
</AutoInsuranceClaim>
and I'm trying to read the Identification node. Here's my code:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(#"..\..\Data.xml");
XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
nsmgr.AddNamespace("ns", "http://www.someurl.com/schemas/AutoInsuranceClaim");
XmlNodeList nodeList = xmlDoc.SelectNodes(#"/ns:AutoInsuranceClaim/Identification", nsmgr);
Console.WriteLine("There are {0} nodes...", nodeList.Count);
I know I should get a least 1 value. My understanding of .NET XML parsing is that if you have a default namespace with no prefix, you have to create your own namespace. But this should have returned 1.
If not, what am I missing?
I might be grasping at straws here, but shouldn't you be namespacing both entities in your xpath expression?
XmlNodeList nodeList = xmlDoc.SelectNodes(#"/ns:AutoInsuranceClaim/ns:Identification", nsmgr);
XElement root = XElement.Load("Data.xml");
var identifications = root.Descendants()
.Where(x => x.Name.LocalName == "Identification")
.ToList()
The problem is that you're trying to find an Identification node without a namespace, but it will have defaulted to the same namespace as the parent due to the xmlns=... part. Try this:
var nodeList = xmlDoc.SelectNodes("/ns:AutoInsuranceClaim/ns:Identification",
nsmgr);
Having tried it myself, it printed a count of 1.
Personally I'd use LINQ to XML instead though, which makes namespace easier handling:
XDocument doc = XDocument.Load(#"..\..\Data.xml");
XNamespace ns = "http://www.someurl.com/schemas/AutoInsuranceClaim";
var nodes = doc.Root.Elements(ns + "Identification");

XML Document Parsing 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;

Categories