How to flat xml to one line in c# code? - c#

How to flat xml to one line in c# code ?
Before:
<CATALOG>
<CD>
<TITLE>Empire Burlesque</TITLE>
<ARTIST>Bob Dylan</ARTIST>
<COUNTRY>USA</COUNTRY>
<COMPANY>Columbia</COMPANY>
<PRICE>10.90</PRICE>
<YEAR>1985</YEAR>
</CD>
</CATALOG>
After:
<CATALOG><CD><TITLE>Empire Burlesque</TITLE><ARTIST>Bob Dylan</ARTIST>COUNTRY>USA</COUNTRY>....

Assuming you're able to use LINQ to XML, and the XML is currently in a file:
XDocument document = XDocument.Load("test.xml");
document.Save("test2.xml", SaveOptions.DisableFormatting);

If you cant use LINQ to XML, you can:
XmlDocument xmlDoc = new XmlDocument()
xmlDoc.LoadXml("Xml as string"); or xmlDoc.Load(filepath)
xmlDoc.InnerXml -- this should return one liner

If you have the XML in a string:
xml.Replace("\n", "").Replace("\r", "")

I know, that this is old question, but it helped me to find XDocument.ToString()
XDocument doc = XDocument.Load("file.xml");
// Flat one line XML
string s = doc.ToString(SaveOptions.DisableFormatting);
Check SaveOptions documentaion

Depends what you are working with and what output you need...
John Skeet's answer works if reading and writing to files.
Aleksej Vasinov's answer works if you want xml without the xml declaration.
If you simply want the xml in a string, but want the entire structure of the xml, including the declaration, ie..
<?xml version "1.0" encoding="utf-16"?> <-- This is the declaration ->
<TheRestOfTheXml />
.. use a StringWriter...
XDocument doc = GetTheXml(); // op's xml
var wr = new StringWriter();
doc.Save(wr, SaveOptions.DisableFormatting);
var s = wr.GetStringBuilder().ToString();

Related

How to parse a XML with nested XML text

Trying to read XML file with nested XML object with own XML declaration. As expected got exception:
Unexpected XML declaration. The XML declaration must be the first node in the document, and no white space characters are allowed to appear before it.
How can i read that specific element as text and parse it as separate XML document for later deserialization?
<?xml version="1.0" encoding="UTF-8"?>
<Data>
<Items>
<Item>
<Target type="System.String">Some target</Target>
<Content type="System.String"><?xml version="1.0" encoding="utf-8"?><Data><Items><Item><surname type="System.String">Some Surname</surname><name type="System.String">Some Name</name></Item></Items></Data></Content>
</Item>
</Items>
</Data>
Every approach i'm trying fail due to declaration exception.
var xml = System.IO.File.ReadAllText("Info.xml");
var xDoc = XDocument.Parse(xml); // Exception
var xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xml); // Exception
var xmlReader = XmlReader.Create(new StringReader(xml));
xmlReader.ReadToFollowing("Content"); // Exception
I have no control over XML creation.
The only way I would know is by getting rid of the illegal second <?xml> declaration. I wrote a sample that will simply look for and discard the second <?xml>. After that the string has become valid XML and can be parsed. You may need to tweak it a bit to make it work for your exact scenario.
Code:
using System;
using System.Xml;
public class Program
{
public static void Main()
{
var badXML = #"<?xml version=""1.0"" encoding=""UTF-8""?>
<Data>
<Items>
<Item>
<Target type=""System.String"">Some target</Target>
<Content type=""System.String""><?xml version=""1.0"" encoding=""utf-8""?><Data><Items><Item><surname type=""System.String"">Some Surname</surname><name type=""System.String"">Some Name</name></Item></Items></Data></Content>
</Item>
</Items>
</Data>";
var goodXML = badXML.Replace(#"<Content type=""System.String""><?xml version=""1.0"" encoding=""utf-8""?>"
, #"<Content type=""System.String"">");
var xmlDoc = new XmlDocument();
xmlDoc.LoadXml(goodXML);
XmlNodeList itemRefList = xmlDoc.GetElementsByTagName("Content");
foreach (XmlNode xn in itemRefList)
{
Console.WriteLine(xn.InnerXml);
}
}
}
Output:
<Data><Items><Item><surname type="System.String">Some Surname</surname><name type="System.String">Some Name</name></Item></Items></Data>
Working DotNetFiddle: https://dotnetfiddle.net/ShmZCy
Perhaps needless to say: all of this would not have been needed if the thing that created this invalid XML would have applied the common rule to wrap the nested XML in a <![CDATA[ .... ]]> block.
The <?xml ...?> processing declaration is only valid on the first line of an XML document, and so the XML that you've been given isn't well-formed XML. This will make it quite difficult to parse as is without either changing the source document (and you've indicated that's not possible) or preprocessing the source.
You could try:
Stripping out the <?xml ?> instruction with regex or string manipulation, but the cure there may be worse than the disease.
The HTMLAgilityPack, which implements a more forgiving parser, may work with an XML document
Other than that, the producer of the document should look to produce well-formed XML:
CDATA sections can help this, but be aware that CDATA can't contain the ]]> end tag.
XML escaping the XML text can work fine; that is, use the standard routines to turn < into < and so forth.
XML namespaces can also help here, but they can be daunting in the beginning.

find if a code exists in xml, using c#

I am starting to work with xml and I am trying to know if there is a way to search a code in this.
Here you are my xml
<?xml version="1.0" encoding="UTF-8"?>
<doctors_hospital>
<doctor>
<code>1757D</code>
<name>one</name>
</doctor>
<doctor>
<code>1169L</code>
<name>two</name>
</doctor>
... continues xml
</doctors_hospital>
I want to look for the code "aab" using c#, and this is my code..
var document =new XmlDocument();
document.Load("O:\\test\\doctor.xml");
XmlNode doctor;
XmlNode root = document.DocumentElement;
doctor = root.SelectSingleNode("/doctors_hospital/doctor/code='aab'");
I can not do this. any suggestion? thanks
Assuming SelectingSingleNode takes a standard XPath expression, what you want to use is
/doctors_hospital/doctor[code='aab']
This will select the entire doctor node with the matching code value.
I agree with Jim, alternatively you could also use Linq to Xml and do this.
XDocument doc = XDocument.Load(filepath);
var codeExist = doc.Descendants("code").Any(x=>(string)x.Value == "1169L");
Check this Demo

Writing XML for dataset containing multiple tables

I'm getting 2 tables in my dataset.
I need to structure my XML as:
<MyRoot>
<Settings>
<Param1>value1</Param1>
<Param2>value2</Param2>
<Param3>value3</Param3>
</Settings>
<Books>
<Book>
<BookId>1000</BookId>
<BookName>Book1</BookName>
</Book>
<Book>
<BookId>2000</BookId>
<BookName>Book2</BookName>
</Book>
</Books>
</MyRoot>
But when I use datSet.WriteXML(); I'm getting XML as:
<MyRoot>
<Settings>
<Param1>value1</Param1>
<Param2>value2</Param2>
<Param3>value3</Param3>
</Settings>
<Book>
<BookId>1000</BookId>
<BookName>Book1</BookName>
</Book>
<Book>
<BookId>2000</BookId>
<BookName>Book2</BookName>
</Book>
</MyRoot>
So, I'm not able to add separate dataset name as "Books" to second table (dataSet.Tables[1]). Is there any way that I can do that?
I tried the below code:
dataSet = GetList();
dataSet.DataSetName = "MyRoot";
dataSet.Tables[0].TableName = "Settings";
dataSet.Tables[1].TableName = "Books";
StringWriter swriter = new StringWriter();
dataSet.WriteXml(swriter);
string dsResult = swriter.ToString();
Thanks.
I don't know a way to tell DataSet.WriteXml directly to write the XML in the way you want it, so you have two big options:
Let DataSet.WriteXml write the XML and modify it afterwards.
Write the serialization code yourself.
For both ways you have different options how to do it. In the first case you can
Load the created XML into a XDocument or XmlDocument and restructure it via code.
Transform your XML via XSLT (I would prefer that over the code solution)
The options in the second case should be obvious. If you create your own XmlWriter and use DataTable.WriteXml to write to it, you should be able to define your own format in a few lines of code.
To choose the right solution for your use case is up to you. I would probably go for the XSTL solution.
You can overwrite the original XML by some code like below.
string filename = "XmlDoc.xml";
System.IO.FileStream stream = new System.IO.FileStream (filename, System.IO.FileMode.Create);
ds.WriteXml(stream);
XmlDocument xmldoc = new XmlDocument("XmlDoc.xml");
XmlNode node1 = xmldoc.CreateNode("Books","Books");
foreach(XmlNode nd in xmldoc.Nodes) {
if(node.value =="Book")
node1.AppendChild(nd);
}
xmldoc.Nodes.Add(node1);
xmldoc.SaveAs("newXmlDoc.Xml");

how Deserializing this type of xml file?

<row>
<id>1</id>
<code></code>
<name></name>
<address></address>
<state></state>
<zone>?</zone>
</row>
<row>
<id>2</id>
<code>AA</code>
<name>Ataria</name>
<address>Sitapur National Highway 24, Uttar Pradesh</address>
<state>Uttar Pradesh</state>
<zone>NER</zone>
</row>
i have no root element in this xml file only row element start and end this xml file.
how Deserializing this type of data ? in c#
If you sure that missing root is only the one issue with your XML - just add it manually:
string fileContent = File.ReadAllText(path);
string rawXml = "<root>" + fileContent + "</root>";
// now you can use LINQ-to-XML or whatever
XDocument xdoc = XDocument.Load(rawXml);
You can also load an XML Fragment directly, via
XmlReaderSettings settings = new XmlReaderSettings();
settings.ConformanceLevel = ConformanceLevel.Fragment;
using (XmlReader reader = XmlReader.Create("tracelog.xml", settings))
{
while (reader.Read())
{
// Process each node of the fragment,
// possibly using reader.ReadSubtree()
}
}
You would create XElements by passing the results of reader.ReadSubTree() to XElement.Load(...).
Well to start with, it's not an XML file - or at least, it doesn't represent an XML document.
One option would be to copy the file into a new file which does have document start/end tags... then you can load it as a normal document. Just create a file, write a document start tag, copy the contents of this file, then write a document end tag, and close the file handle. You could even do this in memory.
Alternatively, it may be possible to read it as it is, in fragments - possibly via XmlReader. I can't say it's something I've done, and I'd generally encourage you to create a full XML file instead, as then you'll be on more familiar territory.
its not an XML file if it doesn't have the root. parser will throw an error if you try to parse it. you can do this way
<?xml version="1.0"?>
<Root>
--- add your file content here
</Root>
then give this file path to the parser.

How to access XML String values in C#?

I'm learning to use ReST Web services and I need to find out how to get a specific value from the xml string that is returned. How can I simply get 1 value from an xml String? All I want is one value. Is there some way to convert this string into something with an indexer?
I'm using Yahoo Geocoding service. Results:
<ResultSet version="1.0">
<Error>0</Error>
<ErrorMessage>No error</ErrorMessage>
<Locale>us_US</Locale>
<Quality>87</Quality>
<Found>1</Found>
−
<Result>
<quality>85</quality>
<latitude>86.457310</latitude>
<longitude>-73.262245</longitude>
<offsetlat>46.457311</offsetlat>
<offsetlon>-73.262071</offsetlon>
<radius>500</radius>
<name/>
<line1>1234 N Main St</line1>
<line2>Anytown, New York 12345</line2>
<line3/>
<line4>United States</line4>
<house>1234</house>
<street>N Main St</street>
<xstreet/>
<unittype/>
<unit/>
<postal>12345</postal>
<neighborhood/>
<city>New York</city>
<county>Albany County</county>
<state>New York</state>
<country>United States</country>
<countrycode>US</countrycode>
<statecode>NY</statecode>
<countycode/>
<uzip>12345</uzip>
<hash>E692D20CBDF86A2E</hash>
<woeid>12783988</woeid>
<woetype>11</woetype>
</Result>
</ResultSet>
You could use Linq to XML
XDocument xmlfile= XDocument.Load("PATH TO XML DOC");
var test = from xml in xmlfile.Descendants("item_name")
select new { Title = (string)xml.Element("title").Value };
That's one way.
Use XPath to address the node you are interested in:
http://msdn.microsoft.com/en-us/library/d271ytdx(v=VS.90).aspx
To transform XML string into an XML document
XmlDocument doc = new XmlDocument();
doc.LoadXml(yourString);
Here is a good introduction to XPath: http://www.codeproject.com/KB/cpp/myXPath.aspx
See my question on Easiest way to read XML with attributes. I found that using xsd.exe to generate a xsd which allows you managed access to the XML was the simplest way to access the XML data. LINQ2XML was also pretty easy to use.

Categories