get specific node from XML using XDOCUMENT - c#

I have an XML document with ISO-8859-1 encoding.
I can load the XML with XDOCUMENT, but i can't storage a specific node.
Can somebody help me with this?
The xml:
<?xml version="1.0" ?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<TERMEKADATOutput xmlns="http://xmlns.oracle.com/orawsv/PUPHAX/PUPHAXWS">
<RETURN>
<OBJTERMEKADAT>
<TTT>210037069</TTT>
<TK>OGYI-T-04617/05</TK>
</OBJTERMEKADAT>
</RETURN>
</TERMEKADATOutput>
</soap:Body>
</soap:Envelope>
And the code:
XDocument xmlDoc = null;
using (StreamReader oReader = new StreamReader(#"C:\Users\maruzsama\source\repos\EPPuphax\EPPuphax\asd.xml", Encoding.GetEncoding("ISO-8859-1")))
{
xmlDoc = XDocument.Load(oReader); //this working fine
var result = from q in xmlDoc.Descendants("OBJTERMEKADAT")
select new
{
asd = q.Element("TTT").Value
};
Console.ReadKey();
}
I need the data from the TTT node (210037069)

Try following changes :
XDocument xmlDoc = null;
using (StreamReader oReader = new StreamReader(#"C:\Users\maruzsama\source\repos\EPPuphax\EPPuphax\asd.xml", Encoding.GetEncoding("ISO-8859-1")))
{
xmlDoc = XDocument.Load(oReader); //this working fine
XElement TERMEKADATOutput = xmlDoc.Descendants().Where(x => x.Name.LocalName == "TERMEKADATOutput").First();
XNamespace ns = TERMEKADATOutput.GetDefaultNamespace();
var result = from q in TERMEKADATOutput.Descendants(ns + "OBJTERMEKADAT")
select new
{
asd = q.Element(ns + "TTT").Value
};
Console.ReadKey();
}

Related

Unable to use LINQ to XML to loop through xml document

I'm trying to get the element values of the following XML document using LINQ but I'm getting "Object reference not set to an instance of an object.";
XML:
<soapenv:Envelope xmlns:soapenv=http://schemas.xmlsoap.org/soap/envelope/
xmlns:xsd=http://www.w3.org/2001/XMLSchema xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance>
<soapenv:Body>
<ns1:GetContactResponse soapenv:encodingStyle=http://schemas.xmlsoap.org/soap/encoding/ xmlns:ns1=http://DefaultNamespace>
<GetContactReturn xsi:type="ns2:Response" xmlns:ns2=http://getContact.contact.V300>
<Contact xsi:type="ns3:Contact" xmlns:ns3=http://_contact.contact.V300>
<Address xsi:type="xsd:string">123 test</Address>
<Address2 xsi:type="xsd:string"/>
<City xsi:type="xsd:string">Los Angeles</City>
<CountryCode xsi:type="xsd:string">US</CountryCode>
<StateCode xsi:type="xsd:string">CA</StateCode>
<ZipCode xsi:type="xsd:string">90001</ZipCode>
</Contact>
<Errors soapenc:arrayType="ns4:Error[0]" xsi:type="soapenc:Array" xmlns:ns4=http://response.base.V300 xmlns:soapenc=http://schemas.xmlsoap.org/soap/encoding//>
<IsSuccessful xsi:type="xsd:boolean">true</IsSuccessful>
<RecordCount xsi:type="xsd:double">1.0</RecordCount>
</GetContactReturn>
</ns1:GetContactResponse>
</soapenv:Body>
</soapenv:Envelope>
I'm using the following to loop through:
using (StreamReader rd = new StreamReader(services.GetResponseStream()))
{
var ServiceResult = rd.ReadToEnd();
XDocument xdoc = new XDocument();
xdoc = XDocument.Parse(ServiceResult);
var xDocResult = (from x in xdoc.Descendants("Contacts")
select new Location
{
Address = x.Element("Address").Value,
Address2 = x.Element("Address2").Value,
city = x.Element("City").Value,
statecode = x.Element("StateCode").Value,
zipcode = x.Element("ZipCode").Value
});
}
I'm assuming it's because there is no root. How do I get the values of the individual elements?
Your xml has lots of errors. I'm using StringReader. You should replace with StreamReader. Here is correction
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<ns1:GetContactResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="http://DefaultNamespace">
<GetContactReturn xsi:type="ns2:Response" xmlns:ns2="http://getContact.contact.V300">
<Contact xsi:type="ns3:Contact" xmlns:ns3="http://_contact.contact.V300">
<Address xsi:type="xsd:string">123 test</Address>
<Address2 xsi:type="xsd:string"/>
<City xsi:type="xsd:string">Los Angeles</City>
<CountryCode xsi:type="xsd:string">US</CountryCode>
<StateCode xsi:type="xsd:string">CA</StateCode>
<ZipCode xsi:type="xsd:string">90001</ZipCode>
</Contact>
<Errors soapenv:arrayType="ns4:Error[0]" xsi:type="soapenc:Array" xmlns:ns4="http://response.base.V300 xmlns:soapenc=http://schemas.xmlsoap.org/soap/encoding"/>
<IsSuccessful xsi:type="xsd:boolean">true</IsSuccessful>
<RecordCount xsi:type="xsd:double">1.0</RecordCount>
</GetContactReturn>
</ns1:GetContactResponse>
</soapenv:Body>
</soapenv:Envelope>
Here is the c# code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
string xml = File.ReadAllText(FILENAME);
StringReader reader = new StringReader(xml);
XDocument doc = XDocument.Load(reader);
XElement contact = doc.Descendants().Where(x => x.Name.LocalName == "Contact").FirstOrDefault();
XNamespace ns = contact.GetDefaultNamespace();
string address = (string)contact.Element(ns + "Address");
string address2 = (string)contact.Element(ns + "Address2");
string city = (string)contact.Element(ns + "City");
string country = (string)contact.Element(ns + "CountryCode");
string state = (string)contact.Element(ns + "StateCode");
string zip = (string)contact.Element(ns + "ZipCode");
}
}
}

Read XML NodeList

I am trying to parse an XML response from a REST call. I can read the XML just fine with my stream reader but when I try to select the first node, it brings back nothing. Here is my XML:
<?xml version="1.0" encoding="UTF-8" standalone="true"?>
<slot_meta_data xmlns:ns2="http://www.w3.org/2005/Atom">
<product id="MDP">
<name>MDP</name>
</product>
<product id="CTxP">
<name>CTxP</name>
</product>
<product id="STR">
<name>STR</name>
</product>
<product id="ApP">
<name>ApP</name>
<slot>
<agent_id>-1111</agent_id>
<agent_name>ApP</agent_name>
<index_id>-1</index_id>
<alias>App Alias</slot_alias>
</slot>
</product>
<product id="TxP">
<name>TxP</name>
<slot>
<agent_id>2222</agent_id>
<agent_name>App2</agent_name>
<index_id>-1</index_id>
<alias>App2 Alias</slot_alias>
</slot>
</product>
</slot_meta_data>
Here is my code
string newURL = "RESTURL";
HttpWebRequest request = WebRequest.Create(newURL) as HttpWebRequest;
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
StreamReader reader = new StreamReader(response.GetResponseStream());
XmlDocument xdoc = new XmlDocument();
xdoc.Load(response.GetResponseStream());
XmlNodeList list = xdoc.SelectNodes("/slot_meta_data[#*]");
foreach (XmlNode node in list)
{
XmlNode product = node.SelectSingleNode("product");
string name = product["name"].InnerText;
string id = product["id"].InnerText;
Console.WriteLine(name);
Console.WriteLine(id);
Console.ReadLine();
}
When I debug list, it has a count of 0.
Using xml linq
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication22
{
class Program
{
const string FILENAME = #"c:\TEMP\TEST.XML";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
var results = doc.Descendants("product").Select(x => new {
name = (string)x.Element("name"),
slot = x.Elements("slot").Select(y => new {
agent_id = (int)y.Element("agent_id"),
agent_name = (string)y.Element("agent_name"),
index_id = (int)y.Element("index_id"),
slot_alias = (string)y.Element("slot_alias")
}).FirstOrDefault()
}).ToList();
}
}
}

Update xml file with xmltextReader in c#

I have xml file like this test.xml:
<?xml version="1.0" encoding="utf-8" ?>
<Message>
<Item Name ="msg1" Status ="false"/>
<Item Name="msg2" Status="false"/>
</Message>
System.Xml.XmlTextReader textReader = new System.Xml.XmlTextReader(test.xml);
System.Xml.XmlDocument xdoc = new System.Xml.XmlDocument();
xdoc.Load(test.xml);
var testreader = xdoc.DocumentElement.ChildNodes;
string name = string.Empty;
string value = string.Empty;
if (message.MsgType == 10005)
{
value = "true";
}
else if (message.MsgType == 10002)
{
value = "false";
}
foreach (var mychild in testreader)
{
var childatt = ((System.Xml.XmlElement)mychild);
name = childatt.Attributes["Name"].Value;
value = childatt.Attributes["Status"].Value;
}
What I have to do to following thing:
I have to save updated value in xml file with xmltestReader and xmldocument
I'm getting request from third client about messageID so I have to check it's exist in xml file or not (e.g get request for msg1 so I have to match it xml file it's there or not).
hope I'm clear with my question.
//Get Message
//txtsearch text u have to pass message Id
var xmlFilePath = Server.MapPath("Test.xml");
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(xmlFilePath);
XmlNodeList nodeList = xmlDoc.DocumentElement.SelectNodes("/TableMessage/Message");
string msgID = "",msgname="";
foreach (XmlNode node in nodeList)
{
if (node.SelectSingleNode("Message_Details").InnerText == "True" && node.SelectSingleNode("Message_id").InnerText==txtsearchtext.Text)
{
msgID = node.SelectSingleNode("Message_id").InnerText;
msgname = node.SelectSingleNode("Message_name").InnerText;
}
}
//store Updated Xml in ur project xml
//get the information from end user and pass the value to correspoding fields
XmlDocument xmlEmloyeeDoc = new XmlDocument();
xmlEmloyeeDoc.Load(Server.MapPath("~/Test.xml"));
XmlElement ParentElement = xmlEmloyeeDoc.CreateElement("Message");
XmlElement ID = xmlEmloyeeDoc.CreateElement("Message_id");
ID.InnerText = "6";
XmlElement message = xmlEmloyeeDoc.CreateElement("Message_name");
message.InnerText = "Message6";
XmlElement Details = xmlEmloyeeDoc.CreateElement("Message_Details");
Details.InnerText = "True";
ParentElement.AppendChild(ID);
ParentElement.AppendChild(message);
ParentElement.AppendChild(Details);
xmlEmloyeeDoc.DocumentElement.AppendChild(ParentElement);
xmlEmloyeeDoc.Save(Server.MapPath("~/Test.xml"));
I hope that code will help u
you will customize ur xml file like this
<?xml version="1.0" encoding="utf-8"?>
<TableMessage>
<Message>
<Message_id>Message1</Message_id>
<Message_name>Message1</Message_name>
<Message_Details>True</Message_Details>
</Message>
<Message>
<Message_id>Message2</Message_id>
<Message_name>Message2</Message_name>
<Message_Details>True</Message_Details>
</Message>
<Message>
<Message_id>Message3</Message_id>
<Message_name>Message3</Message_name>
<Message_Details>False</Message_Details>
</Message>
</TableMessage>

How to check a string exists in a xml node's value asp.net

My xml will be like below
<Employee>
<Emp>
<Name id="1" link="/office1/manager"></Name>
<Name id="2" link="/office/sweeper"></Name>
<Name id="3" link="/office2/manager"></Name>
</Emp>
</Employee>
I want to get the "id" of the employees who contains string "manager" in "link"
Using linq to xml:
XDocument doc = XDocument.Load("XMLFilePath");
var selectors = from elements in doc.Elements("Employee").Elements("Emp").Elements("Name")
where elements.Attribute("link").Value.Contains("manager")
select elements;
string ids = string.Empty;
foreach (var element in selectors)
{
ids += element.Attribute("id").Value + ",";
}
Also, for loading from string you can use:
XDocument doc = XDocument.Parse(xmlString);
var xDoc = XDocument.Parse(xml); //XDocument.Load(filename)
var ids = xDoc.Descendants("Name")
.Where(n => n.Attribute("link").Value.Contains("/manager"))
.Select(n => n.Attribute("id").Value)
.ToList();
//SELECT THE VALUES FROM XML USING C#
<?xml version="1.0" encoding="iso-8859-1"?>
<CONFIG>
<UsersList>
<SystemName>DOTNET-PC</SystemName>
<UserName>KARTHIKEYAN</UserName>
<ImagePath>C:\Users\DEVELOPER\AppData\Roaming\Office Messenger\assets\insta.jpg</ImagePath>
<PhotoPath>C:\Users\DEVELOPER\AppData\Roaming\Office Messenger\assets\NoPhoto.png</PhotoPath>
<UserStatus>Available</UserStatus>
<CustomStatus>Available</CustomStatus>
<theme>FF8B0000</theme>
</UsersList>
</CONFIG> //XML DOCUMENT
//C#
DataSet ds = new DataSet();
try
{
ds.ReadXml("C:\\config.xml");
}
catch { };
if (ds.Tables.Count > 0)
{
var results = from myRow in ds.Tables[0].AsEnumerable() where myRow.Field<string> ("SystemName") == SystemInformation.ComputerName select myRow;//ds.Tables[0] is <CONFIG> tag //in where SystemName=My system name to select the values from xml
foreach (var cust in results)
{
string _myName = cust["UserName"].ToString();
string _myLogoPath = cust["ImagePath"].ToString();
string _customStatus = cust["CustomStatus"].ToString();
string _myPhotoPath = cust["PhotoPath"].ToString();
}
}
//CREATE XML FROM C#
XDocument xmlDoc = XDocument.Load("C:\\config.xml");
xmlDoc.Root.Add(new XElement("UsersList", new XElement("SystemName", SystemInformation.ComputerName), new XElement("UserName", SystemInformation.ComputerName), new XElement("ImagePath", _filesPath + "\\insta.jpg"), new XElement("PhotoPath", _filesPath + "\\NoPhoto.png"), new XElement("UserStatus", "Available"), new XElement("CustomStatus", "Available"), new XElement("theme", "000000")));
xmlDoc.Save("C:\\config.xml");

LINQ to XML returns no result

I am using Linq to to parse an XML, but it return no result:
XML:
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<downloadInfoResponse xmlns="http://webService">
<downloadInfoReturn>
<city>city</city>
<companyName>company name</companyName>
</downloadInfoReturn>
</downloadInfoResponse>
</soapenv:Body>
</soapenv:Envelope>
Code:
public class Merc
{
public string CompanyName { get; set; }
}
using (XmlReader reader = XmlReader.Create(new StringReader(result)))
{
XDocument doc = XDocument.Load(reader, LoadOptions.SetLineInfo);
List<Merc> m = (from downloadInfoReturn in doc.Descendants("downloadInfoReturn")
select new Merc
{
CompanyName = downloadMerchantInfoReturn.Element("companyName").Value
}).ToList();
}
Is there any other good method to do it? Thank you.
Your XML file contains namespaces thus you need to specify it when perform querying:
XNamespace xn = "http://webService";
doc.Descendants(xn + "downloadInfoReturn")
Because you are missing the namespace while querying the xml, also your class name doesn't match, try the following code, it works on my side.
List<Merc> m = null;
XNamespace ns = "http://webService";
using (XmlReader reader = XmlReader.Create(new StringReader(result)))
{
XDocument doc = XDocument.Load(reader, LoadOptions.SetLineInfo);
m = (from downloadInfoReturn in doc.Descendants(ns + "downloadInfoReturn")
select new Merc
{
CompanyName = downloadInfoReturn.Element(ns+ "companyName").Value
}).ToList<Merc>();
}
Console.WriteLine(m.Count); // this will show 1

Categories