I have problems with understandig, how to read data from XML.
XML looks like this:
<PosXML version="7.2.0">
<ReadCardResponse>
<ReturnCode>1</ReturnCode>
<Card>
<Pan>222300******5062</Pan>
<Expires>****</Expires>
<CardName>MASTERCARD</CardName>
<CardSource>2</CardSource>
</Card>
</ReadCardResponse>
</PosXML>
I have loaded XML from stream:
XDocument doc;
using (Stream responseStream = httpResponse.GetResponseStream())
{
doc= XDocument.Load(responseStream);
}
Tried this, but it's not working:
XElement returnCode = doc.XPathSelectElement("ReturnCode")
var returnCode = doc.XPathSelectElement(#"PosXML/ReadCardResponse/ReturnCode");
You need to use the full path to the element
Try:
XElement returnCode = doc.Element("ReadCardResponse").Element("ReturnCode")
You can also access elements by XPath, nodes, or some linq query. Try to play around with intellisense of your IDE
Related
I would like to Read and Deserialize more than one XML file into my XML class structure given a list of strings consisting of file names.
Obviously when reading ONE xml file, you can go like this:
XmlRoot file = null;
XmlSerializer ser = new XmlSerializer(typeof(XmlRoot));
using (XmlReader read = XmlReader.Create(FileName))
{
file = (XmlRoot)ser.Deserialize(read);
{
Which will deserialize the XML file into the class structure?
It is not possible to have a list with file names and use a foreach loop to iterate over them, reading and deserializing one by one as it would theoretically result into multiple root elements being read, deserialized and replicated in the class structure.
So in general I would like to deserialize each file and append the required master elements to a root object.
Does anyone know how to accomplish this? It would be of great help.
Thanks in advance!
PS: Excuse me for my English, as I am not a native speaker. If you need further information, just tell me!
I managed to solve the problem for myself.
First i created a XDocument for the first file i read, afterwards i iterate through the other documents creating a new XDocument for every xml file and try to get the elements after the root (Language in my case) and add it to the root of the XDocument created outside the loop.
XDocument lDoc = new XDocument();
int counter = 0;
foreach (var fileName in multipleFileNames)
{
try
{
counter++;
if (lCounter <= 1)
{
doc = XDocument.Load(fileName);
}
else
{
XDocument doc2 = XDocument.Load(fileName);
IEnumerable<XElement> elements = doc2.Element("Language")
.Elements();
doc.Root.Add(elements);
}
}
return Deserialize(lDoc);
Afterwards i call the Deserialize method, deserializing my created XDocument like this:
public static XmlLanguage Deserialize(XDocument doc)
{
XmlSerializer ser = new XmlSerializer(typeof(XmlLanguage));
return (XmlLanguage)ser.Deserialize(doc.CreateReader());
}
I am trying to create an xml in c# and specifying the namespace and then the prefix on each element.
<bk:library xmlns:bk="www.namespace.com/ww">
<bk:books>
<bk:book>
<bk:title>Title </bk:book>
</bk:book>
<bk:books>
</bk:library>
I have done the following code:
XmlDocument doc = new XmlDocument();
root = doc.AppendChild(doc.CreateElement("library"));
var booksNode = root.appendChild(doc.CreateElement("bk","books","www.namespace.com/ww"));
Console.WriteLine(doc.OuterXml);
I get something like this:
<bk:books xmlns:bk="www.namespace.com/ww">
So it outputs both the prefix and the namespace
It doesn't output the xml as I would like it (shown above).
Any idea how I can get the xml to be output like I have shown?
thanks
Try this
XmlDocument doc = new XmlDocument();
XmlElement root = (XmlElement)doc.AppendChild(doc.CreateElement("bk","library","www.namespace.com/ww"));
var booksNode = root.AppendChild(doc.CreateElement("bk", "books", "www.namespace.com/ww"));
Console.WriteLine(doc.OuterXml);
I have to extract a part of an XML. My XML file can contain thousands of nodes and I would like to get only a part of it and have this part as an xml string.
My XML structure:
<ResponseMessage xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<ErrorResponse>
<Code>SUCCESS</Code>
<Message>Success</Message>
</ErrorResponse>
<OutputXml>
<Response>
<Product>
<child1>xxx</child1>
<child2>xxx</child2>
...
</Product>
<Product>
<child1>xxx</child1>
<child2>xxx</child2>
...
</Product>
...
</Response>
</OutputXML>
</ResponseMessage>
I'm getting the XML from a webservice like that:
...
System.Net.WebResponse wResponse = req.GetResponse();
reqstream = wResponse.GetResponseStream();
System.IO.StreamReader reader = new System.IO.StreamReader(reqstream);
System.Xml.Linq.XDocument xmlResponse = System.Xml.Linq.XDocument.Parse(reader.ReadToEnd());
Then I tried to put the XML in a generic collection to process it using linq:
int startIndex = 0;
int nbItem = 25;
System.Text.StringBuilder outputXml = new System.Text.StringBuilder();
System.Collections.Generic.IEnumerable<System.Xml.Linq.XElement> partialList =
xmlResponse.Elements("Response").Skip(startIndex).Take(nbItem);
foreach (System.Xml.Linq.XElement x in partialList)
{
outputXml.Append(x.ToString());
}
My problem is that my list is always empty.
You can use an LINQ To Xml by using the following code:
IEnumerable<XElement> elements = xmlResponse.Root.Element("OutputXml").Element("Response").Elements("Product");
foreach(XElement element in elements)
{
// Do Work Here
}
This will filter the list down to just products and it will select them correctly without using an index. Using indexes with xml is not the greatest idea because the xml can change.
You can use XPathEvaluate to read a subtree.
If your list is empty, chances are it is namespace problem, so you did not account for this namespace in your code xmlns:i="http://www.w3.org/2001/XMLSchema-instance". XDocument/XElement cannot resolve namespaces automatically.
See this topic on how to use namespaces with LINQ-to-XML.
I have a Xdocument that is populated as follows:
XDocument xDoc = XDocument.Parse(new StreamReader(response.GetResponseStream()).ReadToEnd());
This gives me an XDocument that looks as follows:
<GetReportAsXMLString>
<report>
<reportItem Count ="562..................
</GetReportAsXMLStringResult>
Anything between the tag is all just a giant string(Black). How would I get this portion of the document to format as XML? The tag is also part of the string. I just don't know how to make this show it as not XML.
Thanks
It's hard to say from your description, but it looks like you'll need to first parse the response stream (valid xml), which contains another xml document (as a string). You'll need to extract the string from the 'outer' xml document and parse it into a new one:
psuedocode:
XDocument outer = response.GetResponseStream();
String innerXml = outer.Element("report").Value;
XDocument inner = XDocument.Parse(innerXml);
You have this XML content :
<GetReportAsXMLString>
<report>
<reportItem Count =\"562\"/>
<reportItem Count =\"562\"/>
</report>
</GetReportAsXMLString>
and you want to extract only the "reportItem" nodes?
If so you can do this:
string xml = "<GetReportAsXMLString><report><reportItem Count =\"562\"/><reportItem Count =\"562\"/></report></GetReportAsXMLString>";
XDocument xDoc = XDocument.Parse(xml);
IEnumerable<XElement> elList = xDoc.Descendants().Where(x => x.Name.LocalName.Equals("report")).Descendants().Where(x => x.Name.LocalName.Equals("reportItem"));
I have a StringBuilder with the contents of an XML file. Inside the XML file is a root tag called <root> and contains multiple <node> tags.
I'd like to parse through the XML to read values of tags within in s, but not sure how to do it.
Will I have to use some C# XML data type for this?
Thanks in advance
StringBuilder sb = new StringBuilder (xml);
TextReader textReader = new StringReader (sb.ToString ());
XDocument xmlDocument = XDocument.Load (textReader);
var nodeValueList = from node in xmlDocument.Descendants ("node")
select node.Value;
You should use classes available in either System.Xml or System.Xml.Linq to parse XML.
XDocument is part of the LINQ extensions for XML and is particularly easy to use if you need to parse through an arbitrary structure. I would suggest using it rather than XmlDocument (unless you have legacy code or are not on .NET 3.5).
Creating an XDocument from a StringBuilder is straightforward:
var doc = XDocument.Parse( stringBuilder.ToString() );
From here, you can use FirstNode, Descendents(), and the many other properties and methods available to walk and examine the XML structure. And since XDocument is designed to work well with LINQ, you can also write queries like:
var someData = from node in doc.Descendants ("yourNodeType")
select node.Value; // etc..
If you are just looking the specifically named nodes then you don't need to load the document into memory, you can process it yourself with an XmlReader.
using(var sr = new StringReader(stringBuilder.ToString)) {
using(var xr = XmlReader.Create(sr)) {
while(xr.Read()) {
if(xr.IsStartElement() && xr.LocalName == "node")
xr.ReadElementString(); //Do something here
}
}
}
use XDocument.Parse(...)
There are several objects at your disposal for working with XML. Look at the System.Xml namespace for objects such as XmlDocument as well as the XmlReader and XmlWriter families of objects. If using C# 3.0+, look at the System.Xml.Linq namespace and the XDocument class.
If you're looking to read all the values in the XML file , you could look into deserializing the XML into a C# data Object.
Deserializing XML into class obj in C#
Yes, I suggest you use an XmlDocument object to parse the content of your string.
Here is an example who print all inner text contained in your tags:
var doc=new XmlDocument();
doc.LoadXml(stringBuilder.TosTring());
XmlNodeList elemList = doc.GetElementsByTagName("node");
for (int i=0; i < elemList.Count; i++)
{
XmlNode node=elemList[i];
Console.WriteLine(node.InnerText);
}
using Node object members, you can also easily extract all you attributes .