This question already has answers here:
Best way to get InnerXml of an XElement?
(15 answers)
Closed 9 years ago.
I'm having a hard time getting the correct value from the innertext of an XElement.
First, here's the XML that I'm using. This is a copy of our production data that results from a process in our workflow. In other words, I can't change the XML, I can only parse it. The element whose innertext I'd like to get has data inside that looks like XML, but it isn't. It is straight text from the tool that produced the XML. The element is called <creatorshapeutildata:
Here is the line of code I've tried:
CreatorShapeUtilData = element.Descendants("creatorshapeutildata").Single().Value;
I've also tried this:
CreatorShapeUtilData = element.Descendants("creatorshapeutildata").First().Value;
I've also tried this:
CreatorShapeUtilData = element.Element("creatorshapeutildata").Value;
Unfortunately, the value that gets returned in every case looks like this:
33012-1true#FFFF003#FFFFFF2743337743358
I need the value returned to look like this:
"<creatorData type="object"><type type="int">33012</type>..."
This piece I'm working on is part of a larger program that uses XDocument, XElement, etc. I know an XmlElement has an InnerText property, but I think XElement does not, since I can't seem to find it in Intellisense.
So, is there any possible way to grab the exact text between the creatorshapeutil tags?
You're trying to get the exact opposite of the InnerText / Value properties: the raw XML content.
You can get the content including the outer node by calling element.ToString().
If you want to exclude the outer tag, you can call String.Concat(element.Nodes()).
Related
I have an xml file that I am trying to parse and load content from the file into a collection of custom classes.
I need to use an XMLnode's InnerXml and extract (or create) an additional collection of XMLNodes from that string.
I've googled as well as I can to find a solution, but nothing quite fits what I'm after. Is it possible to do that?
thanks
This question already has an answer here:
How to Select XML Nodes with XML Namespaces from an XmlDocument?
(1 answer)
Closed 5 years ago.
This a simplified version of a more complex XML that I need to manage with C#.
The problem is that when I try to access to a tag within a namespace, the XPATH does not work.
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml("<s:Body xmlns:s=\"sssssss\"><s:SessionID>abcde</s:SessionID></s:Body>");
string xpath = "//*[local-name()='s:SessionID']";
Context.UserLogger.Info(xmlDoc.SelectSingleNode(xpath).InnerText);
//Object reference not set to an instance of an object
But the code works perfect without the colon on the tag.
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml("<s:Body xmlns:s=\"sssssss\"><SessionID>abcde</SessionID></s:Body>");
string xpath = "//*[local-name()='SessionID']";
Context.UserLogger.Info(xmlDoc.SelectSingleNode(xpath).InnerText);
//abcde
I have ensured on a XPATH validator that the "//*[local-name()='s:SessionID']" works fine.
What I am missing?
Thanks in advance,
I have read info about XmlNamespaceManager but I would prefer to use "direct" paths. The XML is full of NameSpaces and it is dynamic, so its the structure changes quite often.
the function local-name() returns only the local part of a tag name that in your case is exactly SessionID that's why the expression '//*[local-name()='s:SessionID']' doesn't work (you need to compare qualified names not just strings)
From your question it seems to me that your are interested in selecting the SessionsID elements, if it's so use just the xpath expression
string xpath = "//s:SessionID";
if it doesn't works then you probably need to bound the prefix s with the namespace uri s="sssssss" (take from your example)
This question already has an answer here:
Closed 12 years ago.
Possible Duplicate:
extracting the letter in between tags
okie let me give an example we have a file,where i need to open it in c# and scan and extract information ,like i want hi to be extracted which is between tag so only i want that to be extracted and copied to other file ,so what can i do??....and how to start about
<REFER> abcd</REFER>
<BODY>hi</BODY>
<p1>hello</p1>
You probably want to use an HTML-Parser (pick one) and then use it to retrieve the content between the tags.
Well, I'd start with looking in the System.IO namespace in order to learn how to read and write files...
Your data looks like it may be XML, so look at the XmlDocument class in System.Xml or the Linq XDocument class. If it's not XML then you're going to have to parse it yourself, so read up on the String class.
Well, this may be a trivial example, but if your document structure gets any more complex than this, I'd highly recommend HtmlAgilityPack.
For the example given, you'd use it like this:
string html = "<REFER> abcd</REFER><BODY>hi</BODY><p1>hello</p1>";
var doc = new HtmlDocument();
doc.LoadHtml(html);
HtmlNode root = doc.DocumentElement;
HtmlNode body = root.SelectSingleNode("BODY");
string extracted = body.InnerText;
That may seem like overkill; but like I said, if the document structure gets any more complex (I can't imagine that the documents you'll be parsing really look like the example), you'll be glad you did it.
I have an XML document that I load in and try to search with XPath. The root node in this file is <t:Transmission xmlns:t='urn:InboundShipment'> and the file end is properly closed with </t:Transmission>.
My problem is that I cannot walk the tree without using a descendant axis. In other words, I can do: SelectSingleNode("//TransactionHeader[SHIPPERSTATE='CA']") and get a node in return. But I cannot do what should be the equivalent: SelectSingleNode("/Transmission/TransmissionBody/Transaction/TransactionHeader[SHIPPERSTATE='CA']")
If I remove the t: I can do an XPath search on /Transmission and get the whole file. With the t: in there I just get null. Or if I try SelectSingleNode("t:Transmission") I get an error with my XPath statement.
I generally do not need to query the root element, so I should be able to make do with just using the descendant axis for my searches. But the XML looks valid to me and so I'd like to know how to address this. Plus I don't want to ask the client to remove "t:" just because I don't know how to deal with it.
The "t:" is a namespace prefix, which is bound to the namespace 'urn:InboundShipment.' In order to properly handle it, you have to tell c# what the prefix is bound to. This page should explain how to use System.Xml.XmlNamespaceManager to handle the namespace.
Edit: See this answer, as well.
My function iterates through every node of an instance of an XMLDocument. It checks to see if the current node's name is in a lookup list. If it is, it applies appropriate validation to the value of the current node.
When the validation method indicates that the value has been changed, I want to replace the value in the original document with the updated value.
I think the easiest way to achieve this might be to write out to an XMLTextWriter as I process each node in the original XMLDocument, either writing out the original or modified node and value as appropriate. This method would rely on determining whether the current node has any children, or is a stand-alone node.
Is there a better way I could update the values in the original document? I need to end up with the complete XMLDocument, but with updated node values, where appropriate.
Thanks in advance.
Can you not modify the existing nodes (which ate already in the correct structure and in an XMLDocument, then re-serialise the XMLDocument? If the nodes are simple text containters then the
.InnerText
property is the one you want.
I know I always go back to this but this sounds like an example where clever use of apply-templates and ExtensionObjects in XSLT would be efficient.
That said XMLDocument is optimised for modification, so if you were going with a pure programmatic solution I would modify the object directly, not create a new Writer.