in C# how to select specific Data from an XMLDocument? - c#

i got below response through web request
<Shofar Target_="Base" >
<RapidOnSite_Pump Key="1" State="Idle" Amount="20" />
<RapidOnSite_Pump Key="2" State="Idle" Amount="15" />
<RapidOnSite_Pump Key="3" State="Despencing" Amount="25"/>
- <Verb_List>
<Verb_Item Key="1" Execute="RapidOnSite_Pump_AdHoc" Result="OK"
Detail="All Pumpsâ–ş5" />
</Verb_List>
from this string i only want to select Nodes which State is not Idle.
My Code
string responseFromServer = MY_RESPONSE
XmlDocument mainxml = new XmlDocument();
mainxml.LoadXml(responseFromServer);
XmlNodeList xnList = mainxml .SelectNodes("/Shofar/RapidOnSite_Pump [#State!='Idle']");
But by this code i didnt get requirments. can anyone please help me?

In the chat you show real xml. It contains the namespace which must be taken into account!
mainxml.LoadXml(responseFromServer);
XmlNamespaceManager manager = new XmlNamespaceManager(mainxml.NameTable);
manager.AddNamespace("ns", "http://ShofarNexus.com");
XmlNodeList xnList = mainxml.SelectNodes("/ns:Shofar/ns:RapidOnSite_Pump [#State!='Idle']", manager);

You can use XElement to get your work done, unless you want to stick to XmlDocument.
XElement rootElem = XElement.Load(new StringReader(xmlStr));
var rapidOnSitePumpWhichAreNotIdle = rootElem.Descendants("RapidOnSite_Pump").Where(e => e.Attribute("State").Value != "Idle");
At the end you will get IEnumerable<XElement> which can be iterated over.

Related

Extracting objects from xml that uses node prefixes using xpath

I have the following XML in a file called C:\temp\config.xml:
<?xml version="1.0" encoding="utf-8"?>
<dvp:systemConfig xmlns:devop="urn:foo.com:sys:rules">
<dvp:map id="rootFolderMap">
<dvp:entry key="anything" value="folder1"/>
<dvp:entry key="config" value="folder2"/>
<dvp:defaultValue value="folder1" />
</dvp:map>
<dvp:map id="folderMappings">
<dvp:entry key="SYS" value="System" />
<dvp:entry key="OPS" value="Operations" />
<dvp:entry key="DEV" value="Development" />
<dvp:defaultValue value="Miscellaneous" />
</dvp:map>
</dvp:systemConfig>
I am now trying to write C# code that will extract values from this XML. In particular, the list of value properties in the nodes.
List<string> folderNames = new List<string>
XmlDocument doc = new XmlDocument();
doc.Load(#"C:\temp\config.xml");
XmlNamespaceManager nsMgr = new XmlNamespaceManager(doc.NameTable);
XmlNodeList xmlNodeList =
doc.SelectNodes("/systemConfig/map[#id='folderMappings']/entry",nsMgr);
foreach (XmlNode xmlNode in xmlNodeList)
{
// I'm hoping xmlNodeList now contains a list of <dvp:entry> nodes.
string folderName = xmlNode.Attributes["value"].ToString().Trim();
folderNames.Add(folderName);
}
However, this code returns an empty xmlNodeList, so the final loop has no items.
I'm not sure how to use the XmlNamespaceManager to pick up the "dvp" prefix, or whether it figures this out when it loads the XmlDocument from the XML on disk.
Can anyone give me some guidance how one goes about using xpath to retrieve values for xml with prefixed nodes? Unfortunately I do not have the power to change the format of the XML so I have to work with the xml I'm provided with.
thanks heaps,
David.
you can ignore the namespace using local-name()
XmlNodeList xmlNodeList =
doc.SelectNodes("/*[local-name()='systemConfig']/*[local-name()='map'][#id='folderMappings']");

how to get(read) data from xmldocument in windows phone, c#

I'm getting data from a web service in my phone application and get the response to xmldocument like below.
XmlDocument XmlDoc = new XmlDocument();
XmlDoc.LoadXml(newx2);
Ther result of XmlDoc is like below.now I want to get the values from this.
<root>
<itinerary>
<FareIndex>0</FareIndex>
<AdultBaseFare>4719</AdultBaseFare>
<AdultTax>566.1</AdultTax>
<ChildBaseFare>0</ChildBaseFare>
<ChildTax>0</ChildTax>
<InfantBaseFare>0</InfantBaseFare>
<InfantTax>0</InfantTax>
<Adult>1</Adult>
<Child>0</Child>
<Infant>0</Infant>
<TotalFare>5285.1</TotalFare>
<Airline>AI</Airline>
<AirlineName>Air India</AirlineName>
<FliCount>4</FliCount>
<Seats>9</Seats>
<MajorCabin>Y</MajorCabin>
<InfoVia>P</InfoVia>
<sectors xmlns:json="http://james.newtonking.com/projects/json">
</itinerary>
</root>
I tried with this.
XmlNodeList xnList = XmlDoc.SelectNodes("/root[#*]");
but it gives null result. the count is 0. how can I read the data from this.hope your help with this.thanx.
You can use System.Xml.Linq.XElement to parse an xml:
XElement xRoot = XElement.Parse(xmlText);
XElement xItinerary = xRoot.Elements().First();
// or xItinerary = xRoot.Element("itinerary");
foreach (XElement node in xItinerary.Elements())
{
// Read node here: node.Name, node.Value and node.Attributes()
}
If you want to use XmlDocument you can do like this:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xmlText);
XmlNode itinerary = xmlDoc.FirstChild;
foreach (XmlNode node in itinerary.ChildNodes)
{
string name = node.Name;
string value = node.Value;
// you can also read node.Attributes
}
You can get the value of a particular element like,
var fareIndex = XmlDoc.SelectSingleNode("/root/itinerary/FareIndex").InnerText;
If you want to get the list of all elements that come under root/itinerary -
XmlNodeList xnList = XmlDoc.SelectNodes("/root/itinerary/*");
This link might help you.

Tricky to read XML from web service C#

I have looked everywhere, and cannot find anything to help me.
I am writing a program that connects to a webservice and then the webservice sends an XML response. After the response is received I have to retrieve certain values from it, but this is where it gets tricky
Here is a snippet of the returned XML:
<?xml version="1.0"?>
<MobilePortalSellingCategoriesHierarchy xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Response xmlns="http://blabla.com/service/">Successful</Response>
<ResponseNumber xmlns="http://blabla.com/service/">0</ResponseNumber>
<SellingCategoriesHierarchy xmlns="http://tym2sell.com/PortalService/">
<Response>Successful</Response>
<ResponseNumber>0</ResponseNumber>
<SellingCategories>
<PortalSellingCategory>
<SellingCategoryId xsi:nil="true" />
<SellingCategoryName>category1</SellingCategoryName>
<DeliveryMethod />
<DeliveryMethodNumber>0</DeliveryMethodNumber>
<SellingCategories>
<PortalSellingCategory>
<SellingCategoryId xsi:nil="true" />
<SellingCategoryName>category1_Item</SellingCategoryName>
<DeliveryMethod />
<DeliveryMethodNumber>0</DeliveryMethodNumber>
<SellingCategories>
<PortalSellingCategory>
<SellingCategoryId>2</SellingCategoryId>
<SellingCategoryName>Item2</SellingCategoryName>
<DeliveryMethod>Display</DeliveryMethod>
<DeliveryMethodNumber>1</DeliveryMethodNumber>
<VoucherValue>0.00</VoucherValue>
<IsVariablePrice>true</IsVariablePrice>
<MinimumVoucherValue>1.00</MinimumVoucherValue>
<MaximumVoucherValue>1000.00</MaximumVoucherValue>
<VoucherValueIncrement>1.00</VoucherValueIncrement>
<AdditionalInputItems>
<PortalAdditionalInputItem>
<InputItemId>-1</InputItemId>
<Label>Value:</Label>
<IsNumericOnly>true</IsNumericOnly>
<MaximumLength>7</MaximumLength>
<Hidden>false</Hidden>
</PortalAdditionalInputItem>
<PortalAdditionalInputItem>
<InputItemId>4</InputItemId>
<Label>Mobile Number</Label>
<IsNumericOnly>true</IsNumericOnly>
<MaximumLength>15</MaximumLength>
<Hidden>false</Hidden>
</PortalAdditionalInputItem>
</AdditionalInputItems>
<TwoStep>false</TwoStep>
<SelectedIcon>SamplePicture</SelectedIcon>
<UnSelectedIcon>SamplePicture</UnSelectedIcon>
This repeats from the SellingCategories node just under Response for a couple of times.
Here is a Snippet of my code where I get the XML as string.
XmlDocument xml = new XmlDocument();
xml.LoadXml(receivedData);
XmlNodeList xnList = xml.SelectNodes("/MobilePortalSellingCategoriesHierarchy");
foreach (XmlNode xn in xnList)
{
string sellingCategoryName = xn["SellingCategoryName"].InnerText;
string SelectedIcon = xn["SelectedIcon"].InnerText;
string UnSelectedIcon = xn["UnSelectedIcon"].InnerText;
richTextBox1.AppendText(string.Format("Name: {0} {1} {2}", sellingCategoryName, SelectedIcon, UnSelectedIcon));
}
I have tried changing xml.SelectNodes("/MobilePortalSellingCategoriesHierarchy");
to
xml.SelectNodes("/MobilePortalSellingCategoriesHierarchy/SellingCategoriesHierarchy/SellingCategories/PortalSellingCategory");
I need to select each SellingCategoryName and list the SellingCategoryName(s) and all the other items underneath it.
I was hoping to get something in the lines of:
Category1
Category1_Item
Item2
SamplePicture
Sample Picture
Mine only reads the First Node and then returns "Successful" to me.
I havve also tried:
XElement root = XElement.Load("FilePath");
var sellingCategoryNames = from PortalSellingCategory in root.Elements("MobilePortalSellingCategoriesHierarchy")
where (string)PortalSellingCategory.Element("SellingCategoriesHierarchy").Element("SellingCategories").Element("PortalSellingCategory") != ""
select PortalSellingCategory;
foreach (var xEle in sellingCategoryNames)
{
richTextBox1.Text = (string)xEle;
}
Any help would be greatly appreciated.
What you are doing with
xml.SelectNodes("/MobilePortalSellingCategoriesHierarchy");
is selecting your root node, which is just one. Thats why you only get one item in your list back. Is the hierarchy important? I can see that PortalSellingCategory can also be inside another PortalSellingCategory. If not maybe you could try the following select:
xml.SelectNodes("//PortalSellingCategory");
This will search for every node named "PortalSellingCategory" in your response, no mather where in the hierarchy it is.
EDIT:
And yes, you should look out for the namespaces, sry for didnt seeing that.
If you like geeting all the nodes with XPath you must create a new NamespaceManager and at it to your selectNodes call:
XmlDocument xml = new XmlDocument();
xml.LoadXml(data);
XmlNamespaceManager ns = new XmlNamespaceManager(xml.NameTable);
ns.AddNamespace("ns", "http://tym2sell.com/PortalService/");
XmlNodeList xnList = xml.SelectNodes("//ns:PortalSellingCategory", ns);
I would use XElement instead of XMLDocument, and then use Linq to query or pick the elmements like: XElement xContact = ....
int contactno = (int?)xContact.Element("command").Element("contactperson").Attribute("contactpersonid") ?? -1;
if (xContact.Element("command").Element("contactperson").Element("name").Element("firstname") != null)
console.writeline(xContact.Element("command").Element("contactperson").Element("name").Element("firstname").Value);
var doc= new XmlDocument();
doc.Load("FilePath");
var nodeList = xml.GetElementsByTagName("PortalSellingCategory");
Hi,
It returns the collection of nodes, and you just have to query it to get needed informations.
Feel free to ask help if needed.
Dimitri.

Selecting Particular Node List in XML

<Report xmlns="Microsoft.SystemCenter.DataWarehouse.Report.Alert" xmlns:p1="w3.org/2001/XMLSchema-instance"; Name="Microsoft.SystemCenter.DataWarehouse.Report.Alert" p1:schemaLocation="Microsoft.SystemCenter.DataWarehou?Schema=True">
<Title>Alert Report</Title>
<Created>6/27/2013 9:32 PM</Created>
<StartDate>6/1/2013 9:29 PM</StartDate>
<EndDate>6/27/2013 9:29 PM</EndDate>
<TimeZone>(UTC)</TimeZone>
<Severity>Warning, Critical</Severity>
<Priority>Low, Medium, High</Priority>
<AlertTable>
<Alerts>
<Alert>
<AlertName></AlertName>
<Priority></Priority>
</Alert>
</Alerts>
</AlertTable>
</Report>
So I'm trying to pull down the list of nodes that appear under Alerts child. So /Report/AlertTable/Alerts.
I've done very similar before but in this format it is not working for some reason. Can someone point me out in the right direction?
XmlDocument Log = new XmlDocument();
Log.Load("test.xml");
XmlNodeList myLog = Log.DocumentElement.SelectNodes("//Report/AlertTable/Alerts");
foreach (XmlNode alert in myLog)
{
Console.Write("HERE");
Console.WriteLine(alert.SelectNodes("AlertName").ToString());
Console.WriteLine(alert.SelectNodes("Priority").ToString());
Console.Read();
}
EDIT:
One of the responses had me try to use a bunch of namespace with p1 but had no such luck.
EDIT:
Did not work either:
var name = new XmlNamespaceManager(log.NameTable);
name.AddNamespace("Report", "http://www.w3.org/2001/XMLSchema-instance");
XmlNodeList xml = log.SelectNodes("//Report:Alerts", name);
From a site:
nodename Selects all nodes with the name "nodename"
/ Selects from the root node
// Selects nodes in the document from the current node that match the selection no matter where they are
So I believe
"/AlertTable/Alerts"
would work, as that would be 'from the root node' as well as
"Report/AlertTable/Alerts"
XPath Site
Figured this sucker out.
It had to do with the namespace of "Microsoft.SystemCenter.DataWarehouse.Report.Alert". Changing this to anything but that won't read the XML properly.
XmlDocument log = new XmlDocument();
log.Load(#"C:\Users\barranca\Desktop\test.xml");
// XmlNodeList xml = log.SelectNodes("//ns1:Alerts");
var name = new XmlNamespaceManager(log.NameTable);
name.AddNamespace("ns1", "Microsoft.SystemCenter.DataWarehouse.Report.Alert");
XmlNodeList xml = log.SelectNodes("//ns1:Alert", name);
foreach (XmlNode alert in xml)
{
Console.Write("HERE");
XmlNode test = alert.SelectSingleNode("//ns1:AlertName",name);
string testing = test.InnerText;
Console.Write(testing);
}

NodeList.SelectSingleNode() syntax

Having problems getting NodeList.SelectSingleNode() to work properly.
My XML looks like this:
<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>
<inm:Results xmlns:inm="http://www.namespace.com/1.0">
<inm:Recordset setCount="18254">
<inm:Record setEntry="0">
<!-- snip -->
<inm:Image>fileName.jpg</inm:Image>
</inm:Record>
</inm:Recordset>
</inm:Results>
The data is a long series of <inm:Record> entries.
I open the doc and get create a NodeList object based on "inm:Record". This works great.
XmlDocument xdoc = new XmlDocument();
xdoc.Load(openFileDialog1.FileName);
XmlNodeList xRecord = xdoc.GetElementsByTagName("inm:Record");
I start looping through the NodeList using a for loop. Before I process a given entry, I want to check and see if the <inm:Image> is set. I thought it would be super easy just to do
string strImage = xRecord[i].SelectSingleNode("inm:Image").InnerText;
My thinking being, "For the XRecord that I'm on, go find the <inm:Image> value ...But this doesn't work as I get the exception saying that I need a XmlNameSpaceManager. So, I tried to set that up but could never get the syntax right.
Can someone show me how to use the correct XmlNameSpaceManager syntax in this case.
I've worked around the issue for now by looping through all of the childNodes for a given xRecord, and checking the tag once I loop around to it. I would like to check that value first to see if I need to loop over that <inm:Record> entry at all.
No need to loop through all the Record elements, just use XPath to specify the subset that you want:
XmlDocument xdoc = new XmlDocument();
xdoc.Load(openFileDialog1.FileName);
XmlNamespaceManager manager = new XmlNamespaceManager(xdoc.NameTable);
manager.AddNamespace("inm", "http://www.inmagic.com/webpublisher/query");
XmlNodeList nodes = xdoc.SelectNodes("/inm:Results/inm:Recordset/inm:Record[inm:Image != '']", manager);
Using the LINQ to XML libraries, here's an example for retrieving that said node's value:
XDocument doc = XDocument.Load(openFileDialog1.FileName);
List<XElement> docElements = doc.Elements().ToList();
XElement results = docElements.Elements().Where(
ele => ele.Name.LocalName == "Results").First();
XElement firstRecord = results.Elements().Where(
ele => ele.Name.LocalName == "Record").First();
XElement recordImage = firstRecord .Elements().Where(
ele => ele.Name.LocalName == "Image").First();
string imageName = recordImage.Value;
Also, by the way, using Hungarian notation for a type-checked language is overkill. You don't need to prepend string variables with str when it will always be a string.
XmlNamespaceManager nsMgr = new XmlNamespaceManager(xdoc.NameTable);
string strImage = xRecord[i].SelectSingleNode("inm:Image",nsMgr).InnerText;
Should do it.
Using this Xml library, you can get all the records that have an Image child element with this:
XElement root = XElement.Load(openFileDialog1.FileName);
XElement[] records = root.XPath("//Record[Image]").ToArray();
If you want to be sure that the Image child contains a value, it can be expressed like this:
XElement[] records = root.XPath("//Record[Image != '']").ToArray();

Categories

Resources