Returned XML from URL:
<root>
<APIVersion>0.1</APIVersion>
<resource>persons</resource>
<search>givenname</search>
<query>andreas</query>
<limit>400</limit>
<results>
<item>
<persons>
<personId>21168</personId>
<givenName>Andreas</givenName>
<familyName>Garpe</familyName>
<email>andreas.garpe#t-fk.no</email>
<mobilePhone/>
<workPhone/>
<positions>...</positions>
</persons>
</item>
<item>...</item>
<item>...</item>
<item>...</item>
</results>
</root>
(Keep in mind that "item" is the objects with personnel info.)
I have a textbox defined as bunifuTextbox1.
I input a name, and it returns the names from the returned XML result and put all the names returned into a dropdown box.
private void button1_Click(object sender, EventArgs e)
{
string address = "http://ws.t-fk.no/?resource=persons&search=givenname&string=" + bunifuTextbox1.text;
XmlDocument doc1 = new XmlDocument();
doc1.Load(address);
XmlElement root = doc1.DocumentElement;
XmlNodeList nodes = root.SelectNodes("/results/item");
foreach (XmlNode node in nodes)
{
string tempf = node["persons"]["givenName"].InnerText;
bunifuDropdown1.AddItem(tempf);
}
}
I'm not sure why this doesen't work. Any help?
Your XPath is incorrect.
Instead of
XmlNodeList nodes = root.SelectNodes("/results/item");
try
XmlNodeList nodes = root.SelectNodes("results/item");
or
XmlNodeList nodes = root.SelectNodes("./results/item");
or
XmlNodeList nodes = root.SelectNodes("//results/item");
Use "results/item" or "./results/item" for an item element that is a child of a results element that is a child of the root node.
Using "//results/item" will select item elements that are children of results elements where the results element is anywhere in the XML.
Related
In XML Document:
Foo.xml
<products>
<product>
<id>1</id>
<name>Foo</name>
</product>
<product>
<id>2</id>
<name>Bar</name>
</product>
</products>
How to get this root element, iterate over his child elements and get their properties?
Bar.cs
XmlDocument doc = new XmlDocument();
doc.Load(path + "/foo.xml");
XmlNode mainNode = doc.DocumentElement.SelectSingleNode("products");
XmlNode root = mainNode.FirstChild; //null
foreach (XmlNode node in mainNode)
{
int id = Convert.ToInt32(node["id"].InnerText);
string name = node["name"].InnerText);
list.Items.Add(id);
list.Items.Add(name);
}
This code implicates that mainNode is null. What is the best practise of doing that?
The DocumentElement is the outermost element of the XML, i.e. the <products> element. You can't select another <products> element below it.
What you can do:
XmlNode mainNode = doc.SelectSingleNode("products");
or
XmlNode mainNode = doc.DocumentElement;
or
XmlNode mainNode = doc.DocumentElement.SelectSingleNode("//products");
The second one is probably the fastest, since it does not need to parse and process a query. The last one is overkill and should be avoided for clean code reasons (KISS principle).
I want get <SNILS> node:
<ArrayOfEmployee xmlns=""
xmlns:i="http://www.w3.org/2001/XMLSchema-instance" version="2.0.11"
formatVersion="2.0" system="ARM">
<Employee>
<AdditionalLaborAgreement i:nil="true" /> <CertificateEducationList>
<Document> <SNILS>1111111111111</SNILS>
</Document>
</CertificateEducationList>
</Employee>
Code:
XmlNodeList nodes = xml.GetElementsByTagName("Employee");
XmlNode node = xml.SelectSingleNode("SVED_PR_GS/ZGLV/FILENAME");
int Count = 2;
foreach (XmlNode n in nodes)
{
XmlNode smr_vsi = n.SelectSingleNode("SNILS");
Console.WriteLine(n.SelectSingleNode(smr_vsi.InnerText));
}
Error: Console.WriteLine(n.SelectSingleNode(smr_vsi.InnerText));
The object reference does not point to an instance of the object.
Your XML is malformed. Its missing </ArrayOfEmployee> element.
You can get the desired node in one of the 2 ways:
// Provide full XPath
XmlNode smr_vsi = n.SelectSingleNode("CertificateEducationList/Document/SNILS");
//Provide find on any path hint.
XmlNode smr_vsi = n.SelectSingleNode("//SNILS");
But, do check for null before using it:
if(smr_vsi != null)
Console.WriteLine(smr_vsi.InnerText);
I don't how to extract the values from XML document, and am looking for some help as I'm new to C#
I am using XmlDocument and then XmlNodeList for fetching the particular XML document
Here is my code
XmlNodeList XMLList = doc.SelectNodes("/response/result/doc");
And my XML looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<response>
<result>
<doc>
<long name="LoadID">494</long>
<long name="EventID">5557</long>
<str name="XMLData"><TransactionDate>2014-05-28T14:17:31.2186777-06:00</TransactionDate><SubType>tblQM2222Components</SubType><IntegerValue title="ComponentID">11111</IntegerValue></str></doc>
<doc>
<long name="LoadID">774</long>
<long name="EventID">5558</long>
<str name="XMLData"><TransactionDate>2014-05-28T14:17:31.2186777-06:00</TransactionDate><SubType>tblQM2222Components</SubType><IntegerValue title="ComponentID">11111</IntegerValue></str></doc>
</result>
</response>
In this i have to fetch every the XMLData data that is under every doc tag and i have to fetch last doc tag EventID.
var xml = XDocument.Parse(xmlString);
var docs = xml.Root.Elements("doc");
var lastDocEventID = docs.Last()
.Elements("long")
.First(l => (string)l.Attribute("name") == "EventID")
.Value;
Console.WriteLine ("Last doc EventId: " +lastDocEventID);
foreach (var doc in docs)
{
Console.WriteLine (doc.Element("str").Element("TransactionDate").Value);
}
prints:
Last doc EventId: 5558
2014-05-28T14:17:31.2186777-06:00
2014-05-28T14:17:31.2186777-06:00
You can use two XPath expressions to select the nodes you want. To answer each part of your question in turn:
To select all of the XMLData nodes:
XmlNodeList XMLList
= doc.SelectNodes("/response/result/doc/str[#name='XMLData']");
To select the last EventId:
XmlNode lastEventIdNode =
doc.SelectSingleNode("/response/result/doc[position() =
last()]/long[#name='EventID']");
If not all doc nodes are guaranteed to have an event id child node, then you can simply:
XmlNodeList eventIdNodes =
doc.SelectNodes("/response/result/doc[long[#name='EventID']]");
XmlNode lastNode = eventIdNodes[eventIdNodes.Count - 1];
That should give you what you've asked for.
Update;
If you want the XML data inside each strXml element, you can use the InnerXml property:
XmlNodeList xmlList
= doc.SelectNodes("/response/result/doc/str[#name='XMLData']");
foreach(XmlNode xmlStrNode in xmlList)
{
string xmlInner = xmlStrNode.InnerXml;
}
There's one result tag short in your xml.
Try using this. It's cleaner too imho
XmlNodeList docs = doc.SelectSingleNode("response").SelectSingleNode("result").SelectNodes("doc");
Then you can use a combination of SelectSingleNode, InnerText, Value to get the data from each XmlNode in your list.
For example if you want the EventID from the first doc tag:
int eventID = int.Parse(docs[0].SelectSingleNode("long[#name='EventID']").InnerText);
I have an eConnect outgoing document pulled from MSMQ, i need to loop through the line items.
I've tried:
XmlNodeList nodes = root.SelectNodes("/Sales_History_Transaction/eConnect/SO_Hist_Trans/Line");
(and several other attempts) with no success...
Here is the XML, how can i get a collection of Line items from the "Line" nodes so that i can then get the line item details?
<Sales_History_Transaction:root>
<eConnect ACTION="1" Requester_DOCTYPE="Sales_History_Transaction" DBNAME="TWO" TABLENAME="SOP30200" DATE1="2013-05-03T09:24:09.970" SOPNUMBE="999999" SOPTYPE="3">
<SO_Hist_Trans>
<SOPNUMBE>999999</SOPNUMBE>
<SOPTYPE>3</SOPTYPE>
<Line>
<CMPNTSEQ>0</CMPNTSEQ>
<LNITMSEQ>998777</LNITMSEQ>
<ITEMNMBR>0099999</ITEMNMBR>
<ITEMDESC>Laptop</ITEMDESC>
</Line>
<Line>
<CMPNTSEQ>0</CMPNTSEQ>
<LNITMSEQ>777</LNITMSEQ>
<ITEMNMBR>0099</ITEMNMBR>
<ITEMDESC>Desktop</ITEMDESC>
</Line>
<Line>
<CMPNTSEQ>0</CMPNTSEQ>
<LNITMSEQ>679777</LNITMSEQ>
<ITEMNMBR>0569</ITEMNMBR>
<ITEMDESC>Memory</ITEMDESC>
</Line>
</SO_Hist_Trans>
</eConnect>
</Sales_History_Transaction:root>
Your xml is not well-formed.
The root tag seems to consist of an undeclared namespace Sales_History_Transaction and the element name root. Have you missed the line in which Sales_History_Transaction is defined?
Once you have valid xml, it should be as simple (depending on namespaces) as:
var xdoc = XDocument.Parse(yourXml);
var nodes = xdoc.Descendants("Line");
Does this do the trick for your example? Or is this the same you tried that failed?
XmlDocument doc1 = new XmlDocument();
doc1.Load("yoururl"); //I don't know from where you load
XmlElement root = doc1.DocumentElement;
XmlNodeList nodes = root.SelectNodes("/Sales_History_Transaction/eConnect/SO_Hist_Trans/Line");
foreach (XmlNode node in nodes) {
Console.Out.WriteLine(node["CMPNTSEQ"].InnerText);
Console.Out.WriteLine(node["LNITMSEQ"].InnerText);
Console.Out.WriteLine(node["ITEMNMBR"].InnerText);
Console.Out.WriteLine(node["ITEMDESC"].InnerText);
Console.Out.WriteLine("------------------------");
}
Figured it out:
XmlNodeList nodes = xmlDocument.GetElementsByTagName("Line");
foreach (XmlNode node in nodes)
{
string txt = node["ElementName"].InnerText;
}
this enumerates through all the "Line" elements in the XML.
Xml code:
<Report>
<ChartData>
<ListName>area</ListName>
<ViewName>Selecte List</ViewName>
<YAxisFields>
<YAxisField>
<Name>Scheduled Start Date/Time</Name>
<DataType>DateTime</DataType>
<Category>Year</Category>
</YAxisField>
</YAxisFields>
<XAxisFields>
<XAxisField>
<Name>Release Type</Name>
<DataType>String</DataType>
<Category>
</Category>
</XAxisField>
</XAxisFields>
</ChartConfig>
</Report>
I got the value for the subnode listname and viewname by using the
below code,
XmlDocument doc = new XmlDocument();
doc.Load("XmlFileName");
XmlNodeList node = doc.SelectNodes("Report/ChartData");
foreach (XmlNode xn in node)
{ xn["ListName"].InnerXml = chartname;
xn["ViewName"].InnerXml = SelectedList;
**xn["YAxisFields/YAxisField"].InnerXml = yaxisfield; //not working, need to get the value for this xml node,need help in this line dono how to proceed**
doc.Save("XmlFilename");
}
First i have tried with code like this instead of above code,in this
i need to create number of objects in order get the value for each
node so i tried by creating object for xmlnodelist then i used
foreach loop to get the value for each node but in this couldnt get
the value for YAxisFields/YAxisField because it also has parent node
as YAxisFields and subnode as YAxisField so there is only way to
create number of objects for xmlnode or is there any other way to do
this?
XmlDocument doc = new XmlDocument();
doc.Load("XmlFileName");
XmlNode Listnode = doc.SelectSingleNode("Report/ChartData/ListName");
XmlNode Viewnode = doc.SelectSingleNode("Report/ChartData/ViewName");
if (Listnode != null)
{
Listnode.InnerXml = chartname;
Viewnode.InnerXml = SelectedList; ;
doc.Save("XmlFileName");
Use Linq to XML XDocument, like this:
doc.Root.Descendants("ChartData").ToList().ForEach(node =>
{
node.Element("ListName").Value = chartname;
node.Element("ViewName").Value = SelectedList;
});