why XMLDocument AppendChild() adds "amp" to a xml node string value? - c#

i have a URL string that i want to insert to an XMLDocument - XmlElement Node:
"http://xx.xxx.xxx.xx4:7000/SomeURL/Some/?Locale=asaf&;Portal=how"
when write this code :
XmlElement NodeElement = xmlDoc.CreateElement(nodeToCreate);
NodeElement.InnerText = propInfo.GetValue(requestData,null).ToString();
additionalParamsNode.AppendChild(NodeElement);
The Text in the 'NodeElement.InnerText' looks fine, but when i do the appendChild()
an "&amp" is written inside the XMLElement additionalParamsNode.
its like the XMLElement takes the InnerXML , not the InnerText of the NodeElement.
i dont want to write the string with "amp" to the XML cause the link wont work.
how do i appendChild without changing "&" to "&amp"?

If I'm remembering correctly, &'s are one of the illegal characters in XML. That's why it is turned into &amp (the html equivalent of &).
You should be able to wrap the data in CDATA tags.
<![CDATA[http://xx.xxx.xxx.xx4:7000/SomeURL/Some/?Locale=asaf&;Portal=how]]>
You might have to parse out the CDATA tags when you are done though.

Related

how to check that xml string contains declaration tag or not?

I want to check that my xml string contains the declartion tag or not?
My xml string has multiple root node, So I can't load that string into XmlDocument.
My problem is: I have an xml with multiple root nodes and I need to do some processing on this xml. So in code, I am adding a root node manually and after processing I am removing that root node. So before adding the root node, i need to check that xml contains the declartion tag or not?
Load your xml to a string with a FileStream and TextReader
Append a wrapper xml tag before and after the string
string wrappedXml = "<wrapper>" + loadedXml + "</wrapper>";
Now load wrappedXml to an XElement via XElement.Parse
Now you can work with your xml and just treat each first child as a root (logically).
You need to do this to be able to check if it's there. Otherwise you are going to have to do some manually string parsing.
No matter how you do it though, in some way or form that file is going to get loaded into memory. So you might as well just load it with a wrapper and use the API to figure it out as opposed to doing a manual parse.

Processing large CDATA section in C#

I am trying to retrieve a cdata section from an xml document, the format of the xml is like this:
<Configuration>
<ConfigItem>
<Key>Hello World</Key>
<Value><![CDATA[For the value we have a large chunk of XAML stored in a CDATA section]]></Value>
</ConfigItem>
</Configuration>
What I am trying to do is retrieve the XAML from the CDATA section, my code so far is as follows:
XmlDocument document = new XmlDocument();
document.Load("Configuration.xml");
XmlCDataSection cDataNode = (XmlCDataSection) document.SelectSingleNode("//*[local-name()='Value']").ChildNodes[0];
String cdata = cDataNode.Data;
However the cdata string has been truncated and is incomplete, I guess because the actual cdata is too large to fit in the string object.
Whats the correct way to do this?
EDIT:
So my original assumption that the string was too long was incorrect. The problem now is that my CDATA contains a nested CDATA within it. Reading online it appears that the proper way to escape the nested cdata is to use ]]]]><![CDATA[> which this xml is using, but it seems like when I select the node it is escaping at the wrong place.
When there's nested CDATA sections, what you need to do is piece the data back together. At present, you're just selecting ChildNodes[0] and ignoring all of the other children. What you'll probably find is that ChildNodes[1] contains some plain text, and then ChildNodes[2] contains another CDATA section, and so on.
You need to extract all of these, extract the data from the CData sections, and concatenate them all together to get the effective "text" contents of the Value element.

How can I put the <!CDATA> in a XML tag

I'm trying to put <!CDATA> in a specific tag in my XML file, but the result is <![CDATA[mystring]]>
Someone can help me ?
The encoding
XmlProcessingInstruction pi = doc.CreateProcessingInstruction("xml", "version=\"1.0\" encoding=\"utf-8\"");
How I'm doing
texto.InnerText = "<![CDATA[" + elemento.TextoComplementar.ToString() + "]]>";
XmlNode xnode = xdoc.SelectSingleNode("entry/entry_status");
XmlCDataSection CData;
InnerText performs whatever escaping is required.
xnode.InnerText = "Hi, How are you..??";
If you want to work with CDATA node then:
CData = doc.CreateCDataSection("Hi, How are you..??");
You haven't explained how you are creating the XML - but it looks like it's via XmlDocument.
You can therefore use CreateCDataSection.
You create the CData node first, supplying the text to go in it, and then add it as a child to an XmlElement.
You should probably consider Linq to XML for working with XML - in my most humble of opinions, it has a much more natural API for creating XML, doing away with the XML DOM model in favour of one which allows you to create whole document trees inline. This, for example, is how you'd create an element with an attribute and a cdata section:
var node = new XElement("root",
new XAttribute("attribute", "value"),
new XCData("5 is indeed > 4 & 3 < 4"));

Find and replace text inside xml document using regular expression

I am using c# console app to get xml document. Now once xmldocument is loaded i want to search for specific href tag:
href="/abc/def
inside the xml document.
once that node is found i want to strip tag completly and just show Hello.
Hello
I think i can simply get the tag using regex. But can anyone please tell me how can i remove the href tag completly using regex?
xml & html same difference: tagged content. xml is stricter in it's formatting.
for this use case I would use transformations and xpath queries rebuild the document. As #Yahia stated, regex on tagged documents is typically a bad idea. the regex for parsing is far to complex to be affective as a generic solution.
The most popular technology for similar tasks is called XPath. (It is also a key component of XQuery and XSLT.) Would the following perhaps solve your task, too?
root.SelectSingleNode("//a[#href='/abc/def']").InnerText = "Hello";
You could try
string x = #"<?xml version='1.0'?>
<EXAMPLE>
<a href='/abc/def'>Hello</a>
</EXAMPLE>";
System.Xml.XmlDocument doc = new XmlDocument();
doc.LoadXml(x);
XmlNode n = doc.SelectSingleNode("//a[#href='/abc/def']");
XmlNode p = n.ParentNode;
p.RemoveChild(n);
System.Xml.XmlNode newNode = doc.CreateNode("element", "a", "");
newNode.InnerXml = "Hello";
p.AppendChild(newNode);
Not really sure if this is what you are trying to do but it should be enough to get you headed in right direction.

Get XmlNode Open Tag with Attributes

Is it possible to get the open tag from a XmlNode with all attributes, namespace, etc?
eg.
<root xmlns="urn:..." rattr="a">
<child attr="1">test</child>
</root>
I would like to retrieve the entire opening tag, exactly as retrieved from the original XML document if possible, from the XmlNode and later the closing tag. Both as strings.
Basically XmlNode.OuterXml without the child nodes.
EDIT
To elaborate, XmlNode.OuterXml on a node that was created with the XML above would return the entire XML fragment, including child nodes as a single string.
XmlNode.InnerXml on that same fragment would return the child nodes but not the parent node, again as a single string.
But I need the opening tag for the XML fragment without the children nodes. And without building it using the XmlAttribute array, LocalName, Namespace, etc.
This is C# 3.5
Thanks
Is there some reason you can't simply say:
string s = n.OuterXml.Substring(0, n.OuterXml.IndexOf(">") + 1);
I think the simplest way would be to call XmlNode.CloneNode(false) which (according to the docs) will clone all the attributes but not child nodes. You can then use OuterXml - although that will give you the closing tag as well.
For example:
using System;
using System.Xml;
public class Test
{
static void Main()
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(#"<root xmlns='urn:xyz' rattr='a'>
<child attr='1'>test</child></root>");
XmlElement root = doc.DocumentElement;
XmlNode clone = root.CloneNode(false);
Console.WriteLine(clone.OuterXml);
}
}
Output:
<root xmlns="urn:xyz" rattr="a"></root>
Note that this may not be exactly as per the original XML document, in terms of the ordering of attributes etc. However, it will at least be equivalent.
How about:
xmlNode.OuterXML.Replace(xmlNode.InnerXML, String.Empty);
Poor man's solution :)

Categories