Reading and writing XML - c#

I am working on a C# and Android library project. What I am basically trying to do is write a library in Android that will send me crash details onto my server.
I then have a C# console application that runs on my server and processes the data received by Android and from this data I want to generate an XML file, so that another program can read in the XML file and provide a monthly report.
I've got stuck with the best way of writing and reading the XML though.
I've read a lot about it and found various things such as XMLWriter or XMLSerializer but I don't know which works best, nor do I understand entirely how these are implemented.
Below is a basic design of how the XML file should be written, this is what I've written manually to give an understanding of what I want to achieve.
<?xml version="1.0" encoding="utf-8" ?>
<apps>
<app>
<MyApp>
<appID>1</appID>
<applicationID>0027598641</applicationID>
<platform>Android</platform>
<CrashDetails>
<Exceptions>
<Exception>
<CrashID>55</CrashID>
<ExceptionType>NullPointerException</ExceptionType>
<FullException>NullPointerException at line 2</FullException>
<StartDate>01-11-2013 09:52:00</StartDate>
<EndDate>02-11-2013 14:43:13</EndDate>
<AppVersionName>6.1.1.6</AppVersionName>
<stacktrace>NullPointerException at line 2 com.MyCompany.MyApp.MyClass.MyMethod</stacktrace>
<Severity>Critical</Severity>
<OccurrenceCount>9</OccurrenceCount>
</Exception>
<Exception>
<CrashID>56</CrashID>
<ExceptionType>NullPointerException</ExceptionType>
<FullException>NullPointerException at line 2</FullException>
<StartDate>01-11-2013 09:52:00</StartDate>
<EndDate>02-11-2013 14:43:13</EndDate>
<AppVersionName>6.1.1.6</AppVersionName>
<stacktrace>NullPointerException at line 2 com.MyCompany.MyApp.MyClass.MyMethod</stacktrace>
<Severity>Critical</Severity>
<OccurrenceCount>9</OccurrenceCount>
</Exception>
</Exceptions>
</CrashDetails>
</MyApp>
<MyApp1>
<appID>2</appID>
<applicationID>4844354</applicationID>
<platform>Android</platform>
<CrashDetails>
<Exceptions>
<Exception>
<CrashID>55</CrashID>
<ExceptionType>NullPointerException</ExceptionType>
<FullException>NullPointerException at line 2</FullException>
<StartDate>01-11-2013 09:52:00</StartDate>
<EndDate>02-11-2013 14:43:13</EndDate>
<AppVersionName>6.1.1.6</AppVersionName>
<stacktrace>NullPointerException at line 2 com.MyCompany.MyApp.MyClass.MyMethod</stacktrace>
<Severity>Critical</Severity>
<OccurrenceCount>9</OccurrenceCount>
</Exception>
</Exceptions>
</CrashDetails>
</MyApp1>
</app>
</apps>
Thanks for any help you can provide.

Our team typically uses LINQ to XML, which provides a really powerful way to work with XML data (including loading XML from files, parsing XML streams, creating XML document and writing/saving XML to files.)
The following link provides a good overview of LINQ to XML
http://www.dreamincode.net/forums/topic/218979-linq-to-xml/
In addition, you may find “the XML part” section of the following page helpful
http://www.codeproject.com/Articles/24376/LINQ-to-XML
Regards

Personally, I prefer to use LINQ to XML for any XML related stuff in C#. You can create XML Trees, and then persist/serialize those trees to file, XmlWriter, or other types of streams.
But in cases when I need huge performance, I prefer to create XML using StringBuilder class and string concatenation operations.

Related

C# Webservice response xml displaying as pdf

I am new to C# web development. I am developing a software that receives response from webservice in XML format. (includes barcodes generated by webservice).
There is an option given by webservice provider, that i have to add a line
(Example<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">)
as a second line in the xml and display in web browser by using style sheets provided by webservice provider. If i have to choose this option, how can i add that line as second line in the received xml file also how can i map the style sheets provided by the webserive in the project for this xml.
If i dont take that option, Is it possible to display the data in xml as a pdf(includes barcodes generated by webservice), if i dont choose the option .
If I understand your question correctly, you want to:
Add a stylesheet specification to an existing XML
Convert an XML to PDF
1. ADDING A STYLESHEET
There is an option given by webservice provider, that i have to add a line [...] as a second line in the xml and display in web browser by using style sheets
This is done using e.g. Linq, like in this answer.
First of all, I think the example you used, i.e.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
may be inaccurate, as it is the first line of a XSL file (a stylesheet); those kind of files are used to transform an XML into another file (a different XML or an HTML, like in your case). However, you say
using style sheets provided by webservice provider
so my guess is that you already have those stylesheets and you can you use them, rather than creating them yourself.
If so, the line you want to add is like
<?xml-stylesheet type="text/xsl" href="helloWorld.xsl"?>
Let's suppose you already have your XML stored into an XDocument variable named "Document" with its root element being "Root"
var FilePath = "Example.xml";
var Document = XDocument.Load(FilePath);
var Root = XDocument.Descendants("Root").Single();
Then you can add your stylesheet this way, getting a new XML:
var NewDocument = new XDocument(
new XProcessingInstruction("xml-stylesheet", "type='text/xsl'ref='helloWorld.xsl'"),
Root);
2. XML to PDF
There are several ways to do this.
You might parse your XML, retrieve the elements you want to show on your PDF, use a library like iTextSharp to create a specific layout and place their contents on the file.
Or, since you already have an XML and you can transform it to an HTML using an XSL, you can use wkHtmlToPdf.
Let me know if you need more details.

How to place XML Processing Instruction on Line 1 using System.XML.Linq

I am writing a console application that generates an XML file that will be consumed by a server job processing application that was written a long time ago. The server app requires a processing instruction: <?JtJob jobname?>. I'm using C# XDocument to generate my xml:
XDocument xml = new XDocument(new XProcessingInstruction("JtJob", "FieldInspection3_Rejected"),
new XElement("Document",
new XElement("DataFile", tempFileName),
new XElement("FormType","Corrected Form Package"),
new XElement("BYOD_RejectComment",reasonForRejection),
new XElement("BYOD_FromTech",techEmail)
)
);
xml.Save(Path.Combine("C:\\Data", DateTime.Now.ToString("yyyyMMdd_HHmmssffff") + "_Rejected.xml"));
For some reason, the server app requires the processing instruction to be on the first line. If my xml file looks like this:
<?xml version="1.0" encoding="utf-8"?><?JtJob FieldInspection3_Rejected?>
<Document>
<DataFile>C:\Windows\TEMP\tmp387F.tmp</DataFile>
<FormType>Corrected Form Package</FormType>
<BYOD_RejectComment>you're ugly</BYOD_RejectComment>
<BYOD_FromTech>example#gmail.com</BYOD_FromTech>
</Document>
Everything works fine. But when it looks like this:
<?xml version="1.0" encoding="utf-8"?>
<?JtJob FieldInspection3_Rejected?>
<Document>
<DataFile>C:\Windows\TEMP\tmp387F.tmp</DataFile>
<FormType>Corrected Form Package</FormType>
<BYOD_RejectComment>you're ugly</BYOD_RejectComment>
<BYOD_FromTech>example#gmail.com</BYOD_FromTech>
</Document>
It errors. My problem is, using the XDocument code above, it generates the second output.
Without loading my generated xml back in as a string and manipulating the string, is there a way for me to tell XDocument to create the processing instruction on the first line?
I know the blame is definitely to be placed on the server app for not accepting valid XML syntax, but my goal is to get this to work, not fix a 20 year old program.
Edit: Thanks! Using the save override preserved the formatting. Didn't make it all one line, but it allowed me to keep the PI on line 1.
Edit 2: Well, that didn't help me either. But I found out what would help me! XDocument.Save() by default outputs UTF8 With BOM. I changed it to without BOM by using XMLTextWriter and that worked.
What if you used the XDocument.Save(String, SaveOptions) method to get an output all on a single line?
So do this instead:
xml.Save(fileName, SaveOptions.DisableFormatting);
This would force the declaration to be onto the first line with the downside of having the entire document on the first line, but if it works for that program then so be it.
You'll want to use a XDocument.Save() overload that allows you to specify formatting options:
xml.Save(Path.Combine("C:\\Data", DateTime.Now.ToString("yyyyMMdd_HHmmssffff") + "_Rejected.xml"),
SaveOptions.DisableFormatting);
https://msdn.microsoft.com/en-us/library/bb551426(v=vs.110).aspx

Modifying xml file without changing special chars

I have an XML file with structure:
<?xml version='1.0'?>
<a>
<b>
<d>
<LineCode>0</LineCode>
<LineName>Metro</LineName>
<LineDescription>Test C&C all countries with MCFM</LineDescription>
</d>
.......
<e>.....</e>
<f>....</f>
</b>
</a>
In this file I have added section with following code:
XElement newElement = new XElement("e",
new XElement("e1", "test1"),
new XElement("e2", "test2"),
new XElement("e3", "test3 ));
doc.Root.Element("a").Element("d").AddAfterSelf(newElement);
doc.Save(file.Directory + "//" + file.Name);
After i run this code all my special chars used in the initial XML file are modified .
For exemple first row became:
<?xml version="1.0" encoding="utf-8"?>
line became:
<LineDescription>Test C&C all countries with MCFM</LineDescription>
How to add the new section in my XML file without modifying the existing chars?Or how to save without modifying existing special chars?
== Observation #1 ==
<!-- Before: -->
<?xml version='1.0'?>
<!-- After: -->
<?xml version="1.0" encoding="utf-8"?>
Explanation: If the encoding attribute is omitted, utf-8 is the default.
== Observation #2 ==
<!-- Before: -->
&
<!-- After: -->
&
Explanation: These XML entities for representing the ampersand are equivalent.
== Summary ==
The new files are to be used by other applications and it is possible that there
might be problems reading or processing the new files.
Well-behaved XML processing software should treat your before- and after- documents in an equivalent fashion. So, if you encounter problems reading or processing the newly edited XML files, those problems really should be addressed. But it is possible that you may not have the kinds of problems that you anticipate.
If the code processing your file is supposed to handle standard XML, it should not matter which form the characters are stored in. Your original file is using the numeric code for the character, while the newly saved file is using the standard entity name. The same applies for the XML header line - version='1.0' and version="1.0" - should be treated exactly the same, and the additional element just identifies which character set was used in writing the file.
Provided your other applications are using standard XML parsers, or custom parsers which are capable of reading standard XML there should be no problem with the modified XML. The only issue you might have is if these other applications cannot read standard XML (ie they assume that all values use single quotes, or they don't correctly process the XML standard entities, etc) - in this case you may need to use a filtering parser on any file sent to those applications to ensure that these requirements are met. (ie a simple SAX parser which writes out the file as the events are triggered using the additional limitations)

Read an XML file from http address

I need to read an xml file using c#/.net from a source like so: https://10.1.12.15/xmldata?item=all
That is basically just an xml file.
StreamReader does not like that.
What's the best way to read the contents of that link?
The file looks like so:
- <RIMP>
- <HSI>
<SBSN>CZ325000123</SBSN>
<SPN>ProLiant DL380p Gen8</SPN>
<UUID>BBBBBBGGGGHHHJJJJ</UUID>
<SP>1</SP>
<cUUID>0000-000-222-22222-333333333333</cUUID>
- <VIRTUAL>...
You'll want to use LINQ to XML to process the XML file. The XDocument.Load Method supports loading an XML document from an URI:
var document = XDocument.Load("https://10.1.12.15/xmldata?item=all");
Another way to do this is using the XmlDocument class. A lot of servers around the world are still running .Net Framework < 3.0 so it's good to know that this class still exists alongside XDocumentin case you're developing an application that will be run on a server.
string url = #"https://10.1.12.15/xmldata?item=all";
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(url);
Maybe the correct answer must starting by reading the initial question about how to "Read an XML file from a URL (or in this case from a Http address)".
I think that can be the best for you see the next easy demos:
(In this case XmlTextReader but today you can use XmlReader instead of XmlTextReader)
http://support.microsoft.com/en-us/kb/307643
(Parallel you could read this documentation too).
https://msdn.microsoft.com/en-us/library/system.xml.xmlreader(v=vs.110).aspx
regards

write xml format log file

Our customized logging sysem saves info into a xml file, like this:
<?xml version="1.0" standalone="yes"?>
<log>
<entry> msg </entry>
<entry> msg </entry>
.
.
.
</log>
Right now we are using StreamWriter to write. If the system crashes (we are in the middle of the development), the end tag/element, </log>, will not be written to the file so the xml file cannot be opened correct with IE. I found there are two possible options to correct this:
Option A: write the end tag at very beginning when file is initialized and then do "insert" for each new entry. right now we are doing "append".
Option B: change to XmlDocument or XmlWriter.
In option A, change "append" to "insert", we need to keep the current location, which is right before the end tag, </log>,. And write from that current location. I didn't find a good way to do this.
In option B, the XmlWriter is almost the same as other stream/writer. No easy way to "insert". The XmlDocument is easy to "insert", but there is no Flush() method to call. we have to Save() to make it write to file. If the Save() means close the stream/file, I don't want to do Load() and Save() for each entry. that will be too expensive, I think.
do you have any good idea about this?
I would set a global exception handler: that way you could finalize the log, but most important you can collect details relevant to the failure (a stacktrace but also memory state, etc.). In my experience this has always been very effective to understand crashes later on when the system is running "in the wild".
You can use the Enterprise Library that allow you to log to a XML file and much much more. I strongly recomend that you, at least, take a look at that.
But if you just want to write a XML log without the other goods from EntLib you can try log4Net for example.
You might want to think about using try ... catch ... finally when writing the log file(s). Then if the main method (for writing the logs) fails, inside of the finally switch to a different method and/or location (if needed) and continue writing the log.
You may want to consider implementing an unhandled exception filter in your application and take care of cleanly flushing your logs there. Take a look at this blog post for information.
Are you sure about using xml for logging?
You can try html for you purposes.
<title>Cool log</title>
<pre>Started</pre>
<pre>Finished</pre>

Categories

Resources