I need to parse XML files where I can't predict the structure. I need to fill a string array with the inner text from every instance of the below tag no matter where they occur in the tree.
<SpecialCode>ABCD1234</SpecialCode>
Is there a simple way to accomplish this using c#?
Solution
If your XML is a string:
XDocument doc = XDocument.Parse("<SpecialCode>ABCD1234</SpecialCode>");
string[] specialCodes = doc.Descendants("SpecialCode").Select(n => n.Value).ToArray();
If your XML is a file:
XDocument doc = XDocument.Load("specialCodes.xml");
string[] specialCodes = doc.Descendants("SpecialCode").Select(n => n.Value).ToArray();
Explanation
XDocument is a handy class that allows for easy XML parsing. You'll need to add a reference to the System.Xml.Linq assembly to your project in order to use it.
The Descendents method will get all children of the XML document, which takes care of your unknown XML structure.
The Select method is a LINQ method and allows us to select a property from each node--in this case, Value.
ToArray converts the IEnumerable result from Select() to your desired result.
XmlDocument doc = new XmlDocument();
doc.Load(FILENAME);
// IN CASE OF STRING, USE FOLLOWING
//doc.LoadXml(XAML_STRING);
XmlNodeList list = doc.DocumentElement.SelectNodes("//SpecialCode");
// prefic will fetch all the SpecialCode tags from xml.
Related
I want to parse different XML that all of them have the same content but with this differences:
Some of the XML are like:
<ds:X509Data><ds:X509Certificate>MIIDtT[...]lLgXlaoNwM=</ds:X509Certificate></ds:X509Data>
Others are:
<dsig:X509Data><dsig:X509Certificate>MIIDtT[...]lLgXlaoNwM=</dsig:X509Certificate></dsig:X509Data>
I want to get the content of the "X509Certificate" node to save it in a file.
For other parts of the XML that are always the same, I was using:
doc.GetElementsByTagName("CountryName");
But I cant do the same here.
What should I do?
You can use XDocument Class and query it with LINQ.
var certificates = from doc in xDoc.Root.documents()
from attr in doc.Attributes()
where attr.Name.ToString().Contains("X509Certificate")
select attr;
You can now loop through certificates and read in the values
I have been trying to deserialize the InnerXML into a class and for some reason the XML keeps changing shape and however many times I try to get the class right it seems to change shape again.
So I have given up and decided to try another method.
Is it possible to retrieve the value of a parameter within the InnerXML manually using c#?
Say for example, my XML innerXML looked like this:
<Timestamp>2014-08-22T21:45:00Z</Timestamp>
<Subscriber>https://www.dogdoza.co.uk</Subscriber>
<Order>
<OrderID>111867</OrderID>
<InvoiceNumber>DOZA-9725410</InvoiceNumber>
<CustomerID>4542</CustomerID>
Is it possible to pull out say the value of Subscriber
If this is possible I can just pull out the values I want manually. Not ideal, but there are only about 10...
I have looked around but not managed to find any code I can get working..
Can anyone please give me any guidance?
Thanks
You can do achieve what you want using LINQ to XML:
XElement myXml = XElement.Load(#"XmlLocationHere");
XElement subscriber = myXml.Descendants("Subscriber").FirstOrDefault();
XElement.Descendants returns a collection of the descendant elements for this document or element, in document order. This method will return an IEnumerable<XElement>, since there might be more than one "Subscriber" element, but in your case, we choose FirstOrDefault, which returns the first occurrence.
Try loading your XML into an XDocument. Then try to use XPathSelectElement to find the specific value you want.
It could be that you need to wrap your inner xml into a root element, because it doesn't accept multiple roots.
Pseudo example:
// set up your xml document
string xml = "<rootelement>" + myInnerXml + "</rootelement>";
XDocument doc = new XDocument();
doc.Parse(xml);
XElement subscriber = doc.XPathSelectElement("/rootelement/Subscriber");
string value = subscriber.Value;
i need to read the value of a particular value in an xml tag, of he solutions i tried i could only find that to get a value of a tag element ,i need to traverse from root element to the child element.is there an optiion where i can directly select a tag and get its value.
In the below xml exa,i need to get 123456 value from the xml using c#.
Ex:-
<ForwardActionRequest xmlns:auth="test" xmlns="http://www.test">
<auth:Authentication>
<auth:AuthenticationData>
<auth:AuthenticationKey>test</auth:AuthenticationKey>
<auth:Username>test</auth:Username>
<auth:Password>test</auth:Password>
</auth:AuthenticationData>
</auth:Authentication>
<SearchOrderReference>
<Reference>123456</Reference>
<AllocatedBy>test</AllocatedBy>
<Description>test</Description>
</SearchOrderReference>
You can use LINQ to XML:
XDocument doc = XDocument.Load(yourXMLText);
string value = doc.Element("SearchOrderReference").Element("Reference").Value;
Please note that I haven't tested this code.
I also encourage you to read more about LINQ to XML here.
Use XmlDocument.SelectSingleNode() to pass in an XPath that will describe the node you want and then extract the value. Use this prototype as you are using namespaces:
http://msdn.microsoft.com/en-us/library/h0hw012b(v=vs.110).aspx
Read about how to instantiate an XmlNamespaceManager() and initialize it with the relevant prefix (it needs not be what you have in the xml itself), then issue the following request:
XmlNode node = doc.SelectSingleNode("/t:ForwardActionRequest/t:SearchOrderReference/t:Reference");
Given that you associate "t" with "http://www.test".
You can deserialize the xml content into a class and directly get the value of the element or you can use LINQ to XML to retrieve the element value,
XDocument doc=XDocument.Load(XMLContent or XMLPath);
string=doc.Element("SearchOrderReference").Element("Reference").Value;
From your post using VS 2005 you can try the XML Reader which reads the XML from string. Here is an example.
using (XmlReader reader = XmlReader.Create(new StringReader(xml)))
{
reader.ReadToFollowing("SearchOrderReference");
reader.ReadToFollowing("Reference");
string r = reader.ReadInnerXml();
}
Try following code:
XDocument doc = XDocument.Load(yourXMLText);
var node = xmlDoc.SelectSingleNode("//SearchOrderReference[#Reference='123456']");
Then extract node's attribute to get the value of reference tag.
Is there any way in XPath DOM Programming with using System.Xml to run selectNodes (XPATH) with a sort parameter?
For example, with the following XML and program writes values in the same order as the document (descending). Is there a way using XPath to get the values in ascending order?
NOTE. Of course, you could pre-sort in XSL, however I need to update the values as I'm looping through them. Since XSL gives me a sorted copy of the elements, not the actual elements themselves, I can't use XSL.
Here's some XML, a program out output
public static void Main() {
XmlDocument xml = new XmlDocument();
xml.Load( "t.xml" );
// SelectNodes gets in document order, but I want in
// ascending order based on #value
foreach( XmlNode ndNode in xml.SelectNodes( "/xml/ele" ) ) {
Console.WriteLine( ndNode.Attributes["value"].Value );
}
}
Here's the XML
<xml>
<ele value='3' test='Third'/>
<ele value='2' test='Second'/>
<ele value='1' test='First'/>
</xml>
Finally the output in document (descending) order. I'd like an XPath that returns the nodes in ascending order.
3
2
1
PS, I'm using System.Xml in Visual Studio 2008 .NET 3.5
XPath doesn't supprort ordering, however you may look at AddSort method.
No, there is no way to do sorting in XPath alone.
But you can easily use LINQ to sort your collection of nodes by whatever values you want.
XmlDocument xml = new XmlDocument ();
xml.LoadXml("<xml> <ele value='3' test='Third'/> <ele value='2' test='Second'/> <ele value='1' test='First'/> </xml>");
var nodes = xml.SelectNodes( "/xml/ele" ).Cast<XmlNode>().OrderBy(ndNode => ndNode.Attributes["value"].Value);
For anyone stumbling upon this question later, XPath 3.1 has a sort function.
<Document>
<Heading1>
<text>Heading Title</text>
<para>para1</para>
<para>para2</para>
<para>para3</para>
</Heading1>
<Heading1>
<text>2nd Heading Title</text>
<para>para4</para>
<para>para5</para>
<para>para6</para>
<Heading2>
<text>3rd Heading Title</text>
<para>para4</para>
<para>para5</para>
</Heading2>
</Heading1>
</Document>
This is XML Document. Now, i want to parse this XML file using C# (4.0). Here, I want to get all the Heading1 elements without using that element name in my program. For example, don't use document.GetElementsByTagName("Heading1");. How i get it. Guide me get out of this issue.
Thanks & Regards.
Using LINQ to XML, you can do:
var headings = yourXDocument.Root.Elements();
Using Nodes() instead of Elements() will also return text nodes and comments, which is apparently not what you want.
You can access the child elements of the document or element through the Elements() method if using LINQ to XML.
XDocument doc = ...;
var query = doc.Root.Elements();
If you're using XmlDocument, this works:
var elements = doc.SelectNodes("/*/*");
That finds all child elements of the top-level element irrespective of any of their names. It's usually safer to specify the names if you know them, so that elements with unexpected names don't get returned in your list - use /Document/Heading1 to do this.