XmlException: Multiple document element was detected - c#

I'm reading a XML file in a very simple way:
XmlTextReader reader = new XmlTextReader(dataPath);
while(reader.Read()){
switch (reader.Name){
case "language":
Debug.Log(reader.ReadString());
break;
case "file":
Debug.Log(reader.ReadString());
break;
case "arg":
Debug.Log(reader.ReadString());
break;
}
}
Where my xml is like this:
<?xml version="1.0" encoding="ISO-8859-1"?>
<config>
<language>EN-US</language>
<file>\File\Doc\sample.txt</file>
</config>
<data>
<arg>LKR</language>
</dara>
My first problem is this:
XmlException: Multiple document element was detected. file:///C:/prj/as/sample.xml Line 7, position 2.
Mono.Xml2.XmlTextReader.ReadStartTag ()
Mono.Xml2.XmlTextReader.ReadContent ()
Mono.Xml2.XmlTextReader.Read ()
System.Xml.XmlTextReader.Read ()
LectorXML.Start () (at as/sampleXML.cs:17)
And second, my output is language and file, but NO arg. Maybe because is a different node? How can i fix this?

You can only have a single node element at the root of your document. You have a <config> and a <data>. Wrap them in a single document element:
<document>
<config>
<language>EN-US</language>
<file>\File\Doc\sample.txt</file>
</config>
<data>
<arg>LKR</arg>
</data>
</document>

Related

XML Name Cannot Begin with the "=" Character

I've read through the similar post of % character but it seems the other issues can be solved in the header line. Are there certain characters not allowed in XML or do I need to format the document another way (In my case the "=" character is giving me trouble when trying to read in the document in C#)?
Name cannot begin with the character ' ', also similar but still fixed by header.
XElement nodes = XElement.Load(filename);
The structure of the XML is below:
<?xml version="1.0" encoding="utf-8"?>
<offer>
<data id="Salary">
<ocrstring>which is equal to $60,000.00 if working 40 hours per week</ocrstring>
<rule>.*(([+-]?\$[0-9]{1,3}(?:,?[0-9]{3})*\.[0-9]{2}))</rule>
<output></output>
</data>
<data id="Hours">
<ocrstring></ocrstring>
<rule>"(?<=working).*?(?=hours)"</rule> <!-- Error Occurring Here -->
<output>bob</output>
</data>
<data id="Location">
<ocrstring></ocrstring>
<rule>Regex2</rule>
<output>LongWindingRoad222</output>
</data>
</offer>
How can I parse the XML Document without getting the Cannot Begin with Character "=" Error
You need to use CDATA sections for all the <rule> elements.
What does <![CDATA[]]> in XML mean?
XML
<?xml version="1.0" encoding="utf-8"?>
<offer>
<data id="Salary">
<ocrstring>which is equal to $60,000.00 if working 40 hours per week</ocrstring>
<rule><![CDATA[.*(([+-]?\$[0-9]{1,3}(?:,?[0-9]{3})*\.[0-9]{2}))]]></rule>
<output></output>
</data>
<data id="Hours">
<ocrstring></ocrstring>
<rule><![CDATA["(?<=working).*?(?=hours)"]]></rule>
<!-- Error Occurring Here -->
<output>bob</output>
</data>
<data id="Location">
<ocrstring></ocrstring>
<rule>Regex2</rule>
<output>LongWindingRoad222</output>
</data>
</offer>

How to I write the contents of XML file(XmlDocument) to text file?

I've xml data inside a local variable xml of type XMLDocument
I wish to save the xml data as it is into a local file.
I've tried something like System.IO.File.WriteAllText(#"C:\MyProfile\OutOut.txt", xml.ToString()); but doesn't work.
Can someone let me know how to proceed for this?
Also let me now if any additional data is needed.
Thanks.
**Update: ** The above task was accomplished by using XmlDocument.Save(FilePath); now just a small update to the questio is like :
If I have to save only a specific parent node along with it's child nodes, how do I proceed
Sample xml file
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Master Name="Accounts">
<Employee>
<Section>
<Details>
<Name="abc" ID="68" PF="9999" />
</Details>
<Department DeptId="12" />
</Section>
<Section>
<Details>
<Name="xyz" ID="69" PF="9999" />
</Details>
<Department DeptId="13" />
</Section>
</Employee>
</Master>
Only Node <Employee> and it's children.
This code converts XmlDocument to text:
using (var stringWriter = new StringWriter())
using (var xmlTextWriter = XmlWriter.Create(stringWriter))
{
xmlDoc.WriteTo(xmlTextWriter);
xmlTextWriter.Flush();
return stringWriter.GetStringBuilder().ToString();
}

Reading data from XML using C#

I have to read the ordertext ("This is an example text") from this XML File:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<order id="">
<users>
<user id="123456" nick="nick" done="false" />
</users>
<machines>
<machine id="1234" sd="1234" ref="" done="false" />
</machines>
<todos />
<ordertexts>
<ordertext>This is an example text </ordertext>
</ordertexts>
</order>
My C# Code looks like this:
XmlDocument xDoc = new XmlDocument();
xDoc.Load(file);
XmlElement node = (XmlElement)xDoc.SelectSingleNode("/order/ordertexts/ordertext");
When I write the selected data in another XML File it looks like this:
<order>
<oldOrderText>System.Xml.XmlElement</oldOrderText>
</order>
What did I do wrong? Is the XPath incorrect?
I am a C# newbie so I really need every help I can get!
Thanks in advance, geibi
What you're looking for is XmlElement.InnerText.
When you get the node using this:
XmlElement node = (XmlElement)xDoc.SelectSingleNode("/order/ordertexts/ordertext");
You still need to use this:
string neededText = node.InnerText;
to get the value of that node.
Suppose that you're writing the results in a console application. If you try to write the node variable, this way:
Console.WriteLine(node);
Since node is not a string, and it's an XmlElement object, the ToString method of XmlElement is going to be called, which returns the object name, hence your new XML had the result as System.Xml.XmlElement and not the desired text.

How to extract a node from xml string C#

I have am xml string like mentioned below:
<?xml version="1.0" encoding="utf-8" ?>
<NodeA xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.air-watch.com/webapi/resources">
<AdditionalInfo>
<Links>
<Link xsi:type="link">
</Link>
</Links>
</AdditionalInfo>
<TotalResults>100</TotalResults>
<NodeB>
<NodeC>
<Id>1</Id>
<A>valueA</A>
<B>valueB</B>
</NodeC>
<NodeC>
<Id>2</Id>
<A>valueA</A>
<B>valueA</B>
</NodeC>
</NodeB>
</NodeA>
I want to extract NodeB and its child nodes (NodeC elements). How can I do it? Below solution does somewhat similar operation but it needs the xml string to be loaded in a XDocument first:
XDocument doc=XDocument.Parse(xmlstr);
String response=doc.Elements("question")
.Where(x=>x.Attribute("id")==id)
.Single()
.Element("response")
.Value;
Is there a way to do it without having to load it in a doc? Some operation on string object itself.
Why cant you use this
XDocument doc=XDocument.Parse(xmlstr);
String response=doc.Elements("question")
.Where(x=>x.Attribute("id")==id)
.Single()
.Element("response")
.Value; ?
you can use Regular Expressions then.

Get and Set XML elements with Namespaces

NEWBIE QUESTION.
I haven't worked that much with xml, nothing like this anyway. I have some XML as shown below that I receive which has several namespaces.
I need to read some values, then update others before returning the revised XML with namespaces intact - don't want them removed.
I am given the path to some of the elements like this cred/sub/aa or trip/items/item[0]/customerInfo/custName.
But it seems that namespaces make it difficult to get to those elements so simply.
Does anybody know how I can read some of the values like NON-SMOKING from custPref or get the value CABBAGE from bossman/zz.
Also, I want to be able to then set a value such as custName to say Mr. X.
Any ideas?
Thanks.
<?xml version="1.0" encoding="utf-16" ?>
<A1 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<cred xmlns="https://blah-blah.com/?foobar">
<sub>
<aa>Zippo</aa>
<bb>lighter</bb>
</sub>
<reqId>
<cc></cc>
<dateOfBirth></dateOfBirth>
</reqId>
</cred>
<reqName xmlns="http://blah-blah/vader/base">qwerty</reqName>
<reqId xmlns="http://blah-blah/vader/base">12345</reqId>
<machine xmlns="http://blah-blah/vader/base">
<qqq>hello</qqq>
<www>goodbye</www>
<eee>99999</eee>
<rrr>88888</rrr>
</machine>
<monkey xmlns="http://blah-blah/vader/base">alskdjfhg</monkey>
<math xmlns="http://blah-blah/vader/base">
<language></language>
</math>
<trip xmlns="http://blah-blah/simple">
<tripOverview xmlns="http://blah-blah/vader/base">
<description></description>
<cost></cost>
</tripOverview>
<bossman xmlns="http://blah-blah/vader/base">
<zz>CABBAGE</zz>
<yy>BANANA</yy>
<xx>MELON</xx>
<ww>SYRUP</ww>
</bossman>
<items>
<item>
<itemSummary xmlns="http://blah-blah/vader/base">
<description></description>
<cost></cost>
<reference></reference>
</itemSummary>
<customerInfo xmlns="http://blah-blah/vader/base">
<custName></custName>
<custPref>NON-SMOKING</custPref>
</customerInfo>
<seatId xmlns="http://blah-blah/vader/base">1</seatId>
</item>
</items>
</trip>
</A1>
string xml = "<Root><Options></Options></Root>";
var xdocs = XDocument.Parse(xml);
xdocs.Descendants().Where(q => q.Name == "Options").FirstOrDefault().Value = "FoundIt";

Categories