CDATA xml parsing - c#

I am getting response in xml format and data are inside cData section in xml nodes. now when i am trying to extract node value then getting value with cdata text.
how can i parse it?
xml:
<myrecords>
<record>
<id><![CDATA[8683]]></id>
<tempid><![CDATA[4567]]></id>
<type><![CDATA[db]]></type>
<params>
<![CDATA[<db> <dbid>254</dbid> <isdb>true</isdb> <mydb>sample</mydb> </db>]]>
</params>
</record>
</myrecords>
i used code to get entire list but i need to get only particular node
foreach (var child in xdoc.Root.Elements())
{
Console.WriteLine("{0}{1}",child.Name,child.Value);
}
the above code list all the cdata value..
i need to get only dbid,isdb,mydb values from the above xml

For the "outer" Xml document, the value is nothing but character data. You'll have to parse that value separately if you want to treat it as Xml.

Related

C# Get nodes inside CDATA of an xml file

I have an xml file which has a CDATA section, which has again xml data. I would need to get a specific node from the xml within CDATA and create one more node of the same type and save the xml.
The replace and save functionality works for 1 input. but i want the tag to be appended in the same file. I hope i am clear!
Have o look at this thread XML parsing : Reading CDATA You probably need to read the CDATA value, convert, create node and write it back

xpath to return value from xml doc

I'm wondering if there is a way to do the following with one xpath expression:
I have an XML doc similar to this but with many 'results',
<result>
<id>1</id>
<name>joe</name>
</result>
<result>
<id>2</id>
<name>jim</name>
</result>
I'm passing a variable into a C# utility along with the xml, and want to return the name where the id = the variable.
I could loop through the xml until reach what I'm after but if there's a handy xpath way to do it I'm listening...
thanks
Assuming you have a root element in there like "results" that XPath can validate, and that you don't have any other nodes named "result"...
//result[id=1]/name
Or you could get the text outright, instead of it being returned in a node
//result[id=1]/name/text()
And if you want to make sure that there's only one result, you could surround it with parens and put a [1] after
(//result[id=1]/name/text())[1]
I would also recommend testing with one of the xpath test sites out there like this one, but beware that different xpath/xml parsers sometimes behave differently.

How can I get only the outer markup of an XML element?

If I have an XmlNode like this
<element attribute="value">
Content
</element>
I can get its InnerXml ("Content"), but how can I get the opposite? That is, just the outer markup separated by its opening tag and closing tags:
<element attribute="value">
and
</element>
I want to exclude the inner xml, so the OuterXml property on the XmlNode class won't do.
Do I have to build it manually by grabbing each piece and formatting them in a string? If so, besides the element's name, prefix and attributes, what other property can XML elements come with that I should remember to account for?
So if I understand you correctly all you want is OuterXml without InnerXml. In that case you can take the outer XML and replace the content with an empty string.
var external = xml.OuterXml.Replace(xml.InnerText, string.Empty);
You could try either of these two options if you don't mind changing the xmlnode:
foreach(XmlNode child in root.ChildNodes)
root.RemoveChild(child);
Console.WriteLine(root.OuterXml);
Or
for (int i=0; i <root.ChildNodes.Count; i++)
{
root.RemoveChild(root.ChildNodes[i]);
}
Note:
//RemoveAll did not work since it got rid of the xml attributes which you wanted to preserve
root.RemoveAll();

Converting string to xml nodes

i have the string, it contains xml nodes, returned from the PHP file.
It's like
<a>1</a><b>0</b><c>4</c>..............
Now i need to find out what value each node have i.e a, b, c......
while loading this string to xmlDocument i'm getting error like "There are multiple root elements".
any solution for this
One of the basic rules for well-formed XML that it has a single root node. With your example, you have multiple roots:
<a>1</a>
<b>0</b>
<c>4</c>
To make it well-formed you will have to make these elements a child of a single root:
<root>
<a>1</a>
<b>0</b>
<c>4</c>
</root>
An XML document that is not well-formed is not really an XML document at all and you will find that no XML parser will be able to read it!
Wrap it in a root element. E.g:
From <a>1</a><b>2</b>...
To <root><a>1</a><b>2</b>...</root>
Then compute as normal.
That is because each element is at the same level. There need to be a "root" that encloses all of them. Wrap them in a arbitrary node, say <root>...</root> then load the new string to the xmlDocument.
This seems like XML, but it's not valid XML. In XML, you have a root element that wraps all of the other elements.
So, if you have that string in str, do this:
str = String.Format("<root>{0}</root>", str);

How to merge two XmlDocuments in C#

I want to merge two XmlDocuments by inserting a second XML doc to the end of an existing Xmldocument in C#. How is this done?
Something like this:
foreach (XmlNode node in documentB.DocumentElement.ChildNodes)
{
XmlNode imported = documentA.ImportNode(node, true);
documentA.DocumentElement.AppendChild(imported);
}
Note that this ignores the document element itself of document B - so if that has a different element name, or attributes you want to copy over, you'll need to work out exactly what you want to do.
EDIT: If, as per your comment, you want to embed the whole of document B within document A, that's relatively easy:
XmlNode importedDocument = documentA.ImportNode(documentB.DocumentElement, true);
documentA.DocumentElement.AppendChild(importedDocument);
This will still ignore things like the XML declaration of document B if there is one - I don't know what would happen if you tried to import the document itself as a node of a different document, and it included an XML declaration... but I suspect this will do what you want.
Inserting an entire XML document at the end of another XML document is actually guaranteed to produce invalid XML. XML requires that there be one, and only one "document" element. So, assuming that your files were as follows:
A.xml
<document>
<element>value1</element>
<element>value2</element>
</document>
B.xml
<document>
<element>value3</element>
<element>value4</element>
</document>
The resultant document by just appending one at the end of the other:
<document>
<element>value1</element>
<element>value2</element>
</document>
<document>
<element>value3</element>
<element>value4</element>
</document>
Is invalid XML.
Assuming, instead, that the two documents share a common document element, and you want to insert the children of the document element from B into A's document element, you could use the following:
var docA = new XmlDocument();
var docB = new XmlDocument();
foreach (var childEl in docB.DocumentElement.ChildNodes) {
var newNode = docA.ImportNode(childEl, true);
docA.DocumentElement.AppendChild(newNode);
}
This will produce the following document given my examples above:
<document>
<element>value1</element>
<element>value2</element>
<element>value3</element>
<element>value4</element>
</document>
This is the fastest cleanest way to merge xml documents.
XElement xFileRoot = XElement.Load(file1.xml);
XElement xFileChild = XElement.Load(file2.xml);
xFileRoot.Add(xFileChild);
xFileRoot.Save(file1.xml);
Bad news. As long as the xml documents can have only one root element you cannot just put content of one document at the end of the second. Maybe this is what you are looking for? It shows how easily you can merge xml files using Linq-to-XML
Alternatively if you are using XmlDocuments you can try make it like this:
XmlDocument documentA;
XmlDocument documentB;
foreach(var childNode in documentA.DocumentElement.ChildNodes)
documentB.DocumentElement.AppendChild(childNode);

Categories

Resources