XDocument just reads the first title? - c#

I need to parse xml but my code just parses one title not all.
How can I parse part ?
This is my code:
CustomResponse itemCustom = new CustomResponse ();
XDocument response = XDocument.Parse(responseXml);
XElement rootElement = response.Root;
foreach (XElement sellResponse in rootElement.Elements())
{
itemCustom .ErrorCode = sellResponse.Element("ErrorCode").Value;
itemCustom .ErrorMessage = sellResponse.Element("ErrorMessage").Value;
itemCustom .CustomerID= sellResponse.Element("CustomerID").Value;
itemCustom .CustomerType= sellResponse.Element("CustomerType").Value;
}
This is my xml:
<?xml version="1.0" encoding="utf-8"?>
<TINS_XML_DATA>
<Header>
<ErrorCode>WAATS</ErrorCode>
<ErrorMessage>UTL</ErrorMessage>
</Header>
<Customer>
<CustomerID>UTL11111111111111111111</CustomerID>
<CustomerType>NSell</CustomerType>
</Customer>
</TINS_XML_DATA>

Try something like this:
foreach (XElement sellResponse in rootElement.Elements())
{
if (sellResponse.Name == "Header")
{
itemCustom.ErrorCode = sellResponse.Element("ErrorCode").Value;
itemCustom.ErrorMessage = sellResponse.Element("ErrorMessage").Value;
}
else if (sellResponse.Name == "Customer")
{
itemCustom.CustomerID = sellResponse.Element("CustomerID").Value;
itemCustom.CustomerType = sellResponse.Element("CustomerType").Value;
}
}
Update: You could also use XPath to find required elements as like below:
var xDoc = new XmlDocument();
xDoc.LoadXml(xml);
var errorMessage = xDoc.SelectNodes("//ErrorMessage")[0].InnerText;

This is my solved:
var xDoc = new XmlDocument();
xDoc.LoadXml(responseXml);
itemSell.ErrorCode = xDoc.SelectNodes("//ErrorCode")[0].InnerText;
itemSell.ErrorMessage = xDoc.SelectNodes("//ErrorMessage")[0].InnerText;
itemSell.CustomerID= xDoc.SelectNodes("//CustomerID")[0].InnerText;

Related

How do I get a specific element in a XML document?

I have a XML file that looks like this:
<Info>
<ID>1</ID>
<Result>
<ID>2</ID>
</Result>
</Info>
I want to count how many Info/Result/ID I have in this file.
I am doing this:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load("myFile.xml");
xmlNodeList MyList = xmlDoc.GetElementsByTagName("Info/Result/ID");
int totalCount = MyList.Count;
// other logic...
The method GetElementsByTagName does not find any "ID"-field.
I want to get the "ID = 2".
How do I do that?
To count all the nodes in "Info/Result/ID" path use this..
var count = xmlDoc.SelectNodes("Info/Result/ID")?.Count ?? 0;
To process these nodes
var nodes = xmlDoc.SelectNodes("Info/Result/ID");
foreach (XmlNode node in nodes) {
var idValue = node.InnerText
// do something
}
Got it working, hereĀ“s how:
public static void MyCountExample(string myXml, out int myID)
{
var stream = new MemoryStream(Encoding.UTF8.GetBytes(myXml ?? ""));
var reader = XmlReader.Create(stream);
myID= 0;
reader.IsStartElement("Info");
while (!reader.EOF)
{
if (reader.ReadToFollowing("Result"))
{
if (reader.ReadToDescendant("ID"))
{
myID++;
else
{
return somethingElse();
}
......

How to get separate values from Xlement

This is a portion of XML I'm trying to parse
<BRTHDATES>
<BRTHDATE value="5/1/1963" code="B"/>
</BRTHDATES>
var birthdates = xmlDoc.XPathSelectElements("/INDV/PERSON/BRTHDATES").Elements().Where(e => e.Name == "BRTHDATE");
xe = birthdates.Elements().Where(e => e.Name == "BRTHDATE");
bbs = from b in birthdates
select new
{
Birthdays = b.FirstAttribute.Value,
Code = b?.Value
};
var status = birthdates.Elements().Where(e => e.Name.LocalName == "BRTHDATE").Single().Value;
When I try to get "Value" from the Element I get an empty string. I can't get anything for the "code" attribute.
It sure seems like this should be a lot easier...
You can try below code. I've already tested through a test project and got the require value.
string personBirthday = string.Empty;
string soapResult = #"<?xml version=""1.0"" encoding=""utf - 8"" ?><INDV> <PERSON> <BRTHDATES><BRTHDATE value = ""5/1/1963"" code = ""B"" /> </BRTHDATES></PERSON></INDV> ";
XmlDocument doc = new XmlDocument();
doc.Load(new StringReader(soapResult));
XmlNodeList person = doc.GetElementsByTagName("BRTHDATES");
if (person[0].ChildNodes.Count > 0)
{
foreach (XmlNode item in person[0].ChildNodes)
{
if (item.Name.Trim().Equals("BRTHDATE"))
{
personBirthday = !string.IsNullOrEmpty(item.Attributes[0].Value) ? item.Attributes[0].Value.Trim() : string.Empty;
}
}
}
Here is the solution
You can select specific Element from a Xml. Just try below sample code
XmlNodeList generalTabNodeList = xmlDocument.SelectNodes("/INDV/PERSON/BRTHDATES");
foreach (XmlNode node in generalTabNodeList)
{
if (node.ChildNodes.Count > 0)
{
string birthdate = !string.IsNullOrEmpty(node.ChildNodes[0].ToString()) ? node.ChildNodes[2].InnerText.ToString() : string.Empty;
}
}
I can't quite follow what you are trying to do, but, this should get you going:
For an XML file that looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<INDV>
<PERSON>
<BRTHDATES>
<BRTHDATE value="5/1/1963" code="B"/>
</BRTHDATES>
</PERSON>
</INDV>
(Note, this is an entire XML document - one that matches your code, not just the snippet you provided (that doesn't match your code))
This code will pick out the value and code attributes:
using (var xmlStream = new FileStream("Test.xml", FileMode.Open))
{
XDocument xmlDocument = XDocument.Load(xmlStream);
var birthDateElements = xmlDocument.XPathSelectElements("/INDV/PERSON/BRTHDATES/BRTHDATE");
var birthDateElement = birthDateElements.FirstOrDefault();
if (birthDateElement != null)
{
var attributes = birthDateElement.Attributes();
var valueAttribute = attributes.Where(a => a.Name == "value");
var codeAttribute = attributes.Where(a => a.Name == "code");
}
}
You can play around with this code to figure out what you want to do. Whatever you do, don't pick out attributes by position, pick them out by name.

Navigate xml nodes;

Hi I have an xml data returned from another service. It looks like this
<?xml version="1.0" encoding="UTF-8"?>
<response xmlns="http://test.com/group/application" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Response>
<Response>
<ReturnCode>0</ReturnCode>
<Message>Sucess</Message>
<Data>PRINT 'This is a test #2'</Data>
</Response>
</Response>
</response>
I need the value of Data, Message and ReturnCode. The value inside the Data(PRINT 'This is a test #2') node could be single line or thousands of lines..
I am using this C# code to get the values
XmlDocument xm = new XmlDocument();
string Response = obj.getContent(str, 1, 73810, SHA);
//Console.WriteLine("Response" + Response);
xm.LoadXml(Response);
Console.WriteLine(xm.InnerXml);
XmlNode oldCd;
XmlElement root = xm.DocumentElement;
Console.WriteLine(root.InnerText);
oldCd = root.SelectSingleNode("/response/Response/Response/ReturnCode/Message/Data/");
static void Main()
{
try
{
svc obj = new svc();
..
//XmlDocument xm = new XmlDocument();
string rsp = obj.getContent(..;
String myEncodedString;
myEncodedString = obj.XmlDecode(rsp);
XNamespace xmlns = XNamespace.Get("http://xxxx.com/xxx/xx");
XDocument doc = XDocument.Parse(myEncodedString);
Console.WriteLine(obj.Return_Message_Data("ReturnCode", myEncodedString));
Console.WriteLine(obj.Return_Message_Data("Message", myEncodedString));
Console.WriteLine(obj.Return_Message_Data("Data", myEncodedString));
Console.ReadLine();
}
catch (Exception e)
{
Console.WriteLine(e);
Console.ReadLine();
}
}
Try this
XmlDocument xml = new XmlDocument();
xml.LoadXml(myXmlString); //myXmlString is the xml file in string //copying xml to string: string myXmlString = xmldoc.OuterXml.ToString();
XmlNodeList xnList = xml.SelectNodes("/responset[#*]/Response");
foreach (XmlNode xn in xnList)
{
XmlNode response = xn.SelectSingleNode("Response");
if (response != null)
{
string rc = response["ReturnCode"].InnerText;
string msg = example["Message"].InnerText;
string data = example["Data"].InnerText;
}
}

Add attributes using XAttribute

I have a root XML which is like this:
<Root xmlns="http://schemas.datacontract.org/2004/07/" xmlns:t="http://www.w3.org/2001/XMLSchema-instance">
<Element1>somevalue</Element1>
<Data/>
<Root>
I need to add few customer related informaiton like (Name, Age etc) under Data Element Node. So, the result I expect is follows:
<Root xmlns="http://schemas.datacontract.org/2004/07/" xmlns:t="http://www.w3.org/2001/XMLSchema-instance">
<Element1>somevalue</Element1>
<Data>
<Name t:type="xs:string" xmlns="" xmlns:s="http://www.w3.org/2001/XMLSchema">Elvis</Name>
<Address t:type="xs:string" xmlns="" xmlns:s="http://www.w3.org/2001/XMLSchema">Some address</Address>
</Data>
<Root>
How can I achieve this? I am using C#, .net 4.0.
I was trying out the below code, but didn't get the result I was expecting:
string strTemplate = "<Root xmlns='http://schemas.datacontract.org/2004/07/' xmlns:t='http://www.w3.org/2001/XMLSchema-instance'><Element1>somevalue</Element1><Data/></Root>";
XDocument doc = XDocument.Parse(strTemplate);
XElement rootElement = doc.Root;
XElement dataElement = null;
foreach (XElement descendant in rootElement.Descendants())
{
if (descendant.Name.LocalName == "Data")
{
dataElement = descendant;
break;
}
}
string cusData = "<CustData><Name>Elvis</Name><Address>XYZ</Address></CustData>";
XElement customerElements = XElement.Parse(cusData);
if (dataElement != null)
{
foreach (XElement custAttributes in customerElements.Descendants())
{
XNamespace t = "http://www.w3.org/2001/XMLSchema-instance";
var attribute = new XAttribute(t + "type", "xs:string");
var attribute1 = new XAttribute(XNamespace.Xmlns + "s", "http://www.w3.org/2001/XMLSchema");
XElement element = new XElement(custAttributes.Name, attribute, attribute1);
element.Value = custAttributes.Value;
dataElement.Add(element);
}
}
string strPayload = doc.ToString();
When I execute the code I get the following:
<Data xmlns="http://schemas.datacontract.org/2004/07/">
<Name t:type="xs:string" xmlns:t="http://www.w3.org/2001/XMLSchema-instance" xmlns="">Elvis</Name>
<Address t:type="xs:string" xmlns:t="http://www.w3.org/2001/XMLSchema-instance" xmlns="">XYZ</Address>
</Data>
Any help appreciated!
Thanks,
M

Reading SOAP xml answer

I have to read a SOAP answer from the file below
<?xml version="1.0"?>
<Envelopes>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope">
<env:Body>
<env:Fault>
<env:Code>
<env:Value>env:Receiver</env:Value>
<env:Subcode>
<env:Value>-1</env:Value>
</env:Subcode>
</env:Code>
<env:Reason>
<env:Text xml:lang="en">CServiceData::SetPropertyValue failed; '</env:Text>
</env:Reason>
<env:Detail>
<Object>4</Object>
<ObjectIndex>1</ObjectIndex>
<Command>AddObject</Command>
<SessionID>B8FE2330-4252-4BB1-A3EE-053F4413A0C0</SessionID>
</env:Detail>
</env:Fault>
</env:Body>
</env:Envelope>
</Envelopes>
I only need the content of the Text tag CServiceData::SetPropertyValue failed;
You can use XPath:
public string GetErrorMessage(string xml)
{
using (StringReader sr = new StringReader(xml))
{
var doc = new XPathDocument(sr);
var nav = doc.CreateNavigator();
var xmlNs = new XmlNamespaceManager(nav.NameTable);
xmlNs.AddNamespace("env", #"http://www.w3.org/2003/05/soap-envelope");
var node = nav.SelectSingleNode("//env:Text", xmlNs);
return node.Value;
}
}
or you can use LINQ To XML:
public string GetErrorMessage(string xml)
{
var doc = XDocument.Parse(xml);
var node = doc.Descendants(XName.Get("Text", #"http://www.w3.org/2003/05/soap-envelope"))
.FirstOrDefault();
return node.Value;
}

Categories

Resources