I got an XML response as:
<Resp>
<status>00</status>
<errorcode></errorcode>
<errordescr></errordescr>
<data>
<Table>
<USERNAME>Name</USERNAME>
<ACCLOCK>N</ACCLOCK>
<EMAILID>Samplemail#gmail.com</EMAILID>
<LASTLOGINDATE>23-03-2015 12:35:40</LASTLOGINDATE>
<LOGINSTATUS>N</LOGINSTATUS>
<MOBILENO>9848022338</MOBILENO>
<PASSWORD>Abcd#1234</PASSWORD>
<PWDCOUNT>0</PWDCOUNT>
<PWDVALIDTO>12-05-2015 12:18:10</PWDVALIDTO>
<DESCRIPTION>Shop Person</DESCRIPTION>
<STATUS>Y</STATUS>
<USRID_FK>100017</USRID_FK>
<ROLE>12</ROLE>
<COUNTRY>61</COUNTRY>
<MERID_FK>100002</MERID_FK>
<GENDER>0</GENDER>
<COUNTRY1>61</COUNTRY1>
<STATE>0</STATE>
<DOB>12-02-1997</DOB>
<STRID_FK>10025</STRID_FK>
</Table>
</data>
I am saving this XML response in the following string:
string response;
I want to split the string response and get values of some tags (EX:-USERNAME, STRID_FK, MERID_FK), to save it in other strings for further usage.
Please help me with this ..
XmlDocument xml = new XmlDocument();
xml.LoadXml(myXmlString);
XmlNodeList xnList = xml.SelectNodes("/data/Table");
foreach (XmlNode xn in xnList)
{
string USERNAME= xn["USERNAME"].InnerText;
string STRID_FK= xn["STRID_FK"].InnerText;
string MERID_FK= xn["MERID_FK"].InnerText;
Console.WriteLine("Name: {0, {1}, {2}", USERNAME, STRID_FK,MERID_FK);
}
or if try directly to select node
xmlDoc.SelectNodes("/data/Table/USERNAME") or
XmlNodeList nodes= doc.GetElementsByTagName("USERNAME");
Another option, this time using Linq to Xml:
var yourXml = XElement.Parse (response); // Parse the response
// Look up specific values by name:
var username = yourXml.Descendants().First(node => node.Name == "USERNAME").Value;
Yet another option is to put all the data from <Table>...</Table> into a dictionary for easy lookup later:
var dict = yourXml.Descendants()
.Where(node => node.Name == "Table")
.Descendants()
.ToDictionary(node => node.Name.ToString(), node => node.Value);
// Look up value using "USERNAME" as key:
var exampleUsername = dict["USERNAME"];
Related
I am trying to read XML using LINQ. Previously I use XMLDocument to read but it gives an error and someone on StackOverflow encourage me to use LINQ.
Below is the code i previously used for the XMLDocument
string soapmessage = #"<?xml version=""1.0"" encoding=""UTF - 8""?>" + "\n" + response.Content;
XmlDocument xml = new XmlDocument();
xml.LoadXml(soapmessage); //loading soap message as string
XmlNamespaceManager manager = new XmlNamespaceManager(xml.NameTable);
manager.AddNamespace("d", "http://tempuri.org/");
manager.AddNamespace("bhr", "http://52.187.127.196:5000/api/gsowebservice.asmx");
XmlNodeList xnList = xml.SelectNodes("//bhr:FourMonthsAhead1Response", manager);
int nodes = xnList.Count;
string Status = xnList[0]["FourMonthsAhead1Result"]["PlantForecastIntervals"]["PlantForecastIntervalNode"]["IntervalStartTime"].InnerText;
Console.WriteLine(Status);
Console.ReadLine();
I am trying to get the <IntervalStartTime> from the first <PlantForecastIntervalNode> into a datetime variable;
Below attaced the XML im trying read:
Below is some of the XML code. I can't paste it here because the code is 2322 lines long so I shortened the code to this.
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<s:Body>
<FourMonthsAhead1Response xmlns="http://tempuri.org/">
<FourMonthsAhead1Result xmlns="LSS.solar.webservice">
<PlantDescription xmlns="http://base.datacontract">*PlantName*</PlantDescription>
<PlantForecastIntervalsCount xmlns="http://base.datacontract">2976</PlantForecastIntervalsCount>
<ForecastStartDate xmlns="http://base.datacontract">2021-10-08T13:35:55.912612</ForecastStartDate>
<ForecastEndDate xmlns="http://base.datacontract">2021-10-08T13:35:55.9126123</ForecastEndDate>
<PlantForecastIntervals xmlns="http://base.datacontract">
<PlantForecastIntervalNode>
<IntervalStartTime>2021-10-01T00:00:00</IntervalStartTime>
<IntervalEndTime>2021-10-01T00:15:00</IntervalEndTime>
<IntervalLength>15</IntervalLength>
<ForecastResultParameter>FourMonthsAhead1</ForecastResultParameter>
<ForecastValue>0</ForecastValue>
<ValueUnit>MW</ValueUnit>
</PlantForecastIntervalNode>
<PlantForecastIntervalNode>
<IntervalStartTime>2021-10-01T00:15:00</IntervalStartTime>
<IntervalEndTime>2021-10-01T00:30:00</IntervalEndTime>
<IntervalLength>15</IntervalLength>
<ForecastResultParameter>FourMonthsAhead1</ForecastResultParameter>
<ForecastValue>0</ForecastValue>
<ValueUnit>MW</ValueUnit>
</PlantForecastIntervalNode>
</PlantForecastIntervals>
</FourMonthsAhead1Result>
</FourMonthsAhead1Response>
</s:Body>
</s:Envelope>
Update
After exploring other threads on StackOverflow I come up with this line below but receive another error of System.UriFormatException: 'Invalid URI: The Uri string is too long.':
XDocument xdoc = XDocument.Load(soapmessage);
var ids = xdoc.Element("FourMonthsAhead1Result")
.Elements("PlantForecastIntervals")
.Elements("<PlantForecastIntervalNode>")
.Select(item => item.Element("IntervalStartTime").Value);
Console.WriteLine(ids);
Try this using LINQ
var response = File.ReadAllText("XMLFile1.xml");
var xe = XElement.Parse(response);
XNamespace ns = "http://base.datacontract";
var obj = xe.Descendants(ns + "PlantForecastIntervals")
.Descendants(ns + "PlantForecastIntervalNode")
.Select(x => x.Element(ns + "IntervalStartTime").Value);
Console.WriteLine(obj);
Look at below solution,
var xmlRead = File.ReadAllText(#"XMLFile1.xml"); /// Add your xml file path
var xElement = XElement.Parse(xmlRead);
XNamespace xNamespace = "http://base.datacontract";
var obj = xElement.Descendants(xNamespace + "PlantForecastIntervals")
.Descendants(xNamespace + "PlantForecastIntervalNode")
.Select(x => x.Element(xNamespace + "IntervalStartTime").Value);
string[] dateTime = obj.ToArray();
foreach (string x in dateTime)
{
Console.WriteLine(x.ToString()); /// it will print time from all IntervalStartTime tags
}
I have an XML file, in this XML you can see the RESPONSE_DATA tag. This tag have some more inner tags. I need to get all the values inside PERSON_DATA tags. Also i need to get all the other value in below xml file.
<?xml version=\"1.0\" encoding=\"utf-16\"?>\r\n
<HUMAN_VERIFICATION xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<RESPONSE_DATA>
<RESPONSE_STATUS>
<ERROR>100</ERROR>
<MESSAGE>successful</MESSAGE>
</RESPONSE_STATUS>
<CONTACT_NUMBER>3120202456011</CONTACT_NUMBER>
<PERSON_DATA>
<NAME>Alex</NAME>
<DATE_OF_BIRTH>10-9-1982</DATE_OF_BIRTH>
<BIRTH_PLACE>Washington</BIRTH_PLACE>
<EXPIRY>2020-12-15</EXPIRY>
</PERSON_DATA>
<CARD_TYPE>idcard</CARD_TYPE>
</RESPONSE_DATA>
</HUMAN_VERIFICATION>
I prefer using Linq to Xml.
var results = doc.Descendants("PERSON_DATA") // Flatten the hierarchy and look for PERSON_DATA
.Select(x=> new
{
NAME = (string)x.Element("NAME"),
DATE_OF_BIRTH = (string)x.Element("DATE_OF_BIRTH"),
BIRTH_PLACE = (string)x.Element("BIRTH_PLACE"),
EXPIRY = (string)x.Element("EXPIRY"),
});
Check the Demo
You can try this code it may be helpful for you.
XmlDocument newdoc = new XmlDocument();
newdoc.InnerXml = " <?xml version=\"1.0\" encoding=\"utf-16\"?><HUMAN_VERIFICATION><RESPONSE_DATA><RESPONSE_STATUS><ERR>100</ERROR><MESSAGE>successful</MESSAGE></RESPONSE_STATUS><CONTACT_NUMBER>3120202456011</ CONTACT _NUMBER><PERSON_DATA><NAME>Alex</NAME><DATE_OF_BIRTH>10-9-1982</DATE_OF_BIRTH><BIRTH_PLACE>Washington</BIRTH_PLACE><EXPIRY>2020-12-15</EXPIRY></PERSON_DATA><CARD_TYPE>idcard</CARD_TYPE></RESPONSE_DATA></HUMAN_VERIFICATION>";
var selectnode = "HUMAN_VERIFICATION/RESPONSE_DATA/PERSON_DATA";
var nodes = newdoc.SelectNodes(selectnode);
foreach (XmlNode nod in nodes)
{
string name = nod["NAME" ].InnerText;
string dob = nod["DATE_OF_BIRTH"].InnerText;
string place = nod["BIRTH_PLACE" ].InnerText;
string expiry = nod["EXPIRY" ].InnerText;
Console.WriteLine("Person: {0} {1} {2} {3}", name, dob, place, expiry);
}
It's really easy and intuitive with System.Xml.Linq.
var xml = "<?xml version=\"1.0\" encoding=\"utf-16\"?>\r\n<HUMAN_VERIFICATION xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">\r\n <RESPONSE_DATA>\r\n <RESPONSE_STATUS>\r\n <ERROR>100</ERROR>\r\n <MESSAGE>successful</MESSAGE>\r\n </RESPONSE_STATUS>\r\n <CONTACT_NUMBER>3120202456011</CONTACT_NUMBER>\r\n <PERSON_DATA>\r\n <NAME>Alex</NAME>\r\n <DATE_OF_BIRTH>10-9-1982</DATE_OF_BIRTH>\r\n <BIRTH_PLACE>Washington</BIRTH_PLACE>\r\n <EXPIRY>2020-12-15</EXPIRY>\r\n </PERSON_DATA>\r\n <CARD_TYPE>idcard</CARD_TYPE>\r\n </RESPONSE_DATA>\r\n</HUMAN_VERIFICATION>";
var document = XDocument.Parse(xml);
var name = document.Element("HUMAN_VERIFICATION").Element("RESPONSE_DATA").Element("PERSON_DATA").Element("NAME").Value;
OR
var personData = document.Element("HUMAN_VERIFICATION").Element("RESPONSE_DATA").Element("PERSON_DATA").Elements().ToDictionary(e => e.Name.ToString(), e => e.Value);
I'm using this xml structure:
<park>
<car title="Ferrari" available="true">
<url>http://www.ferrari.com/</url>
</rss>
</park>
And this is my code in C#:
XmlDocument doc = new XmlDocument();
doc.Load("Settings.xml");
XmlNodeList list = doc.SelectNodes("/park/car");
foreach (XmlNode item in list)
{
string x = item["#title"].InnerText;
}
I just want to get "title" property but i can't get it working. I'm using "#" but without success.
Try this code:
string x = item.Attributes["title"].Value;
I suggest you to use LINQ to XML for parsing xml:
var xdoc = XDocument.Load("Settings.xml");
var titles = xdoc.XPathSelectElements("//park/car")
.Select(c => (string)c.Attribute("title"));
Or without XPath:
var titles = xdoc.Descendants("park")
.Elements("car")
.Select(c => (string)c.Attribute("title"));
Here is the XML sample:
<?xml version="1.0" ?>
<XMLScreen xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<CX>80</CX>
<CY>24</CY>
<Formatted>true</Formatted>
<Field>
<Location position="1" left="1" top="0" length="69" />
<Attributes Base="226" Protected="false" FieldType="High" />
*SDC SCHEDULING CATEGORY UPDATE
</Field>
</XMLScreen>
I want to retrive the Inner text of each field based on its Location position.
What I have so far is:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(myEm.CurrentScreenXML.GetXMLText());
XmlNodeList fields = xmlDoc.GetElementsByTagName("Field");
MessageBox.Show("Field spot: " + i + " Contains: " + fields[i].InnerText);
And I want to be able to just extract the inner text of the field by passing in a number of the location position. So if I say foo[i] I want to be able to get the innertext
*SDC SCHEDULING CATEGORY UPDATE
You should use a xpath search query :
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xml);
int nodeId = 4;
XmlNode node = xmlDoc.SelectSingleNode(String.Format(#"//Location[#position='{0}']", nodeId));
if (node != null)
{
String field = node.ParentNode.InnerText;
}
Something like that, with XDocument instead of XmlDocument (well, if you're not in .net 3.5 or higher, we'll have a problem).
private string GetTextByLocationId(XDocument document, int id)
{
var field = document.Descendants("Field").FirstOrDefault(m => m.Element("Location").Attribute("position").Value == id.ToString());
if (field == null) return null;
return field.Value;
}
and usage
var xDocument = XDocument.Load(<pathToXmlFile or XmlReader or string or ...>);
var result = GetTextByLocationId(xDocument, 1);
EDIT
or if you want a dictionary with :key = position / value = text
private static Dictionary<int, string> ParseLocationAndText(XDocument document)
{
var fields = document.Descendants("Field");
return fields.ToDictionary(
f => Convert.ToInt32(f.Element("Location").Attribute("position").Value),
f => f.Value);
}
Try,
XElement root = XElement.Parse(myEm.CurrentScreenXML.GetXMLText());
XElement field = root.XPathSelectElement(
string.Format("Field[Location/#position='{0}']", 1));
string text = field.Value;
You will need to use the following using to use XPath with XElements.
using System.Xml.XPath;
Assuming I have an XmlDocument like this:
<xmlFile>
<details>
<code1>ADJ</code1>
<code2>ADC </code2>
<Shipment>
<foo></foo>
<bar></bar>
</Shipment>
<Shipment>
<foo></foo>
<bar></bar>
</Shipment>
</details>
<details>
<code1>ADJ</code1>
<code2>SCC </code2>
<Shipment>
<foo></foo>
<bar></bar>
</Shipment>
</details>
</xmlFile>
I need to process each in an xml file but only shipments that fall under the tags with a child node with a value of "ADC". So far I have:
// Assume there is an XmlDocument named xml
XmlNodeList details= xml.GetElementsByTagName("details");
foreach (XmlNode node in details)
{
if (node["code2"].InnerText == "ADC ")
{
// Get each shipment and process it accordingly.
}
}
I can't figure out what to do next. Thanks.
Assuming Data\Sample.xml contains xml as mentioned in the question,
Following is the XLINQ query
XElement root = XElement.Parse(File.ReadAllText(#"Data\Sample.xml"));
var adcShipment = root.Descendants().Where(e=>String.Equals(e.Value, "ADC "));
//next query for nodes/elements inside/next to ADC shipments
XPath can simplify your search for matches:
foreach (XmlNode node in xml.SelectNodes("/xmlFile/details[normalize-space(code2)='ADC']"))
{
string foo = node.SelectSingleNode("foo").InnerText;
string bar = node.SelectSingleNode("bar").InnerText;
}
I'm in the process of adding XPath parsing to this library: https://github.com/ChuckSavage/XmlLib/
I modified it so you can do this:
XElement root = XElement.Load(file);
var shipments = root.XPath("details[starts-with(*,'ADC')]/Shipment");
Long-hand that looks like:
var shipments = root.Elements("details")
.Where(x => x.Elements().Any(xx => ((string)xx).StartsWith("ADC")))
.Elements("Shipment");
This is the sort of thing you're after
XmlNodeList details = xml.GetElementsByTagName("details");
foreach (XmlNode node in details)
{
if (node["code2"].InnerText.Trim() == "ADC")
{
// Get each shipment and process it accordingly.
foreach(XmlNode shipment in node.SelectNodes("Shipment"))
{
var foo = shipment.SelectSingleNode("foo");
var bar = shipment.SelectSingleNode("bar");
}
}
}