C#: Modifying the header of an XML file - c#

I am creating an XML file in C# using a XSD Schema of an InfoPath form.
When I save the IP form without using the code, I get an XML file with the following header:
<?xml version="1.0" encoding="UTF-8"?>
<?mso-infoPathSolution solutionVersion="1.0.0.113" productVersion="14.0.0" PIVersion="1.0.0.0" href="file:///\\Hmfp\mcs-shared\PMU\PMU-shared\Tests\QF%207.5%20PMU%20Project%20Outline%20Form%20F1.0.xsn" name="urn:schemas-microsoft-com:office:infopath:QF-7-5-PMU-Project-Outline-Form-F1-0:-myXSD-2010-07-22T07-48-32" ?>
<?mso-application progid="InfoPath.Document"?>
<my:myFields...
And this file is recognized by InfoPath and uses the correct XSD, thus displaying the XML data in the correct form.
But when I use the code, I get this:
<?xml version="1.0"?>
<myFields...
And this is not recognized nor opened directly by InfoPath; so I would like to insert the two tags in order to keep that functionality, so that the users do not see the difference.
My line of thought is to modify the XML file after it has already been created, saved and closed.
It would be very nice if you could help :D. Thanks in advance..
EDIT: I've finally been able to achieve what I wanted. I made use of both MainMa's and dahlbyk's answers and came up with something that works:
I let the file get saved like before
I created an XmlReader object from the file
I loaded the XmlReader into an XmlDocument object
I created an XmlProcessingInstruction object using XmlDocument.CreateProcessingInstruction
I inserted that PI in the XmlDoc using xmlDoc.InsertAfter(thePI, XmlDoc.FirstChild)
I then created a second PI object
Which I inserted using xmlDoc.InsertAfter(thePI, XmlDoc.FirstChild.NextSibling)
Then I saved the XmlDoc in the file, overwriting it
Anyway, your answers helped me understand many things, which made me find the answer, so thank you very much!!

I would try making an XmlWriter for your FileStream, use WriteProcessingInstruction() to add your headers, then pass the writer into the appropriate overload of Serialize() to capture the rest of the output.

The first three lines of your first code sample are called XML processing instructions (PI). So if you are creating your output XML with XmlDocument, you can use XmlDocument.CreateProcessingInstruction method to add the required PI.
If you are serializing into XML, you can also use XmlTextWriter.WriteProcessingInstruction just before serializing the object.
If for some reasons, you cannot do that, you can also save the file, open it and insert two PI after the first line break, but I highly discourage you to do that, since it will make your code difficult to maintain in future, and slow things down.

Related

How to Read a particular Data from XML file and Write it to an Existing Excel Sheet using c#

i have an xml file, i have some values like good, and bad, with Tag Quality. I want to read the xml file and print the ones which are Bad, in the Excel sheet which is existing. Can anyone help me Please. My XML file looks same as Below. So in that text i want to write entire HYDR. instrument id, HYDR.Quality" Only for Bad Values in HYDR.Quality Element.
<HYDR.Instrument id="ABR">
<HYDR.Quality>Good</HYDR.Quality>
<HYDR.Value>0</HYDR.Value>
</HYDR.Instrument>
<HYDR.Instrument id="ABR_DUMMY">
<HYDR.Quality>Bad</HYDR.Quality>
<HYDR.Value>0</HYDR.Value>
</HYDR.Instrument>
<HYDR.Instrument id="ABR_LOOP_JP">
<HYDR.Quality>Good</HYDR.Quality>
<HYDR.Value>15.208 kg/cm2g</HYDR.Value>
</HYDR.Instrument>
<HYDR.Instrument id="ABR_MOV_12">
<HYDR.Quality>Good</HYDR.Quality>
<HYDR.Value>0</HYDR.Value>
</HYDR.Instrument>
Basically you need to use two libraries to get to the answer you want:
First you need to load the XML file, so I suggest using the Linq library, you can start from here
Then, you need to write the filtered XML elements to excel, I suggest to use the aspose library, you can start learning from here
Using these two libraries, you can achieve what you want.

Omit XML Declaration in DataSet.WriteXMLSchema

i need to serialize a dataset in c# to xml for sending the data to a webservice. I cannot change the webservice so my code has to be changed to fit the requirements of the webservice.
I use dataset.WriteXmlSchema(stream) to write the schema and add dataset.WriteXml(stream) to add the data itself.
The result now looks like following:
<?xml version='1.0'?>
<xs:schema id='DocumentElement' xmlns='' xmlns:xs='http://www.w3.org/2001/XMLSchema' ...
Is there a chance to get rid of the <?xml version='1.0'?> declaration?
I need to encapsulate the XML result of the dataset into other xml data and the xml declation breaks the data i need to send. I didn't want to start with fuzzy string handling and i thought there must be something more straight forward.
Thanks
MadMaxapp
There seems no way to omit the xml declaration. I've implemented some code to remove the first line of the xml. Not nice but it works.

Reading oddly-formatted XML file C#

I need some help with reading an oddly-formatted XML file. Because of the way the nodes and attributes are structured, I keep running into XMLException errors (at least, that's what the output window is telling me; my breakpoints refuse to fire so that I can check it). Anyway, here's the XML. Anyone experienced anything like this before?
<ApplicationMonitoring>
<MonitoredApps>
<Application>
<function1 listenPort="5000"/>
</Application>
<Application>
<function2 listenPort="6000"/>
</Application>
</MonitoredApps>
<MIBs>
<site1 location="test.mib"/>
</MIBs>
<Community value="public"/>
<proxyAgent listenPort="161" timeOut="2"/>
</ApplicationMonitoring>
Cheers
EDIT: Current version of the parsing code (file path shortened - Im not actually using this one):
XmlDocument xml = new XmlDocument();
xml.LoadXml(#"..\..\..\ApplicationMonitoring.xml");
string port = xml.DocumentElement["proxyAgent"].InnerText;
Your problem in loading the XML is that xml.LoadXml expects you to pass the xml document as a string, not a file reference.
Try instead using:
xml.Load(#"..\..\..\ApplicationMonitoring.xml");
Essentially in your original code you are telling it that your xml document is
..\..\..\ApplicationMonitoring.xml
And I'm sure you can now see why there is a parse exception. :) I've tested this with your xml document and the modified load and it works fine (except for the issue that Only Bolivian Here pointed out with the fact that your inner Text is not going to return anything.
For completeness you probably want:
XmlDocument xml = new XmlDocument();
xml.Load(#"..\..\..\ApplicationMonitoring.xml");
string port = xml.DocumentElement["proxyAgent"].Attributes["listenPort"].Value;
//And to get stuff more specifically in the tree something like this
string function1 = xml.SelectSingleNode("//function1").Attributes["listenPort"].Value;
Note the use of the Value property on the attribute and not the ToString method which won't do what you are expecting.
Exactly how you extract the data from the xml is probably dependant on what you are doing with it. For example you may want to get a list of Application nodes to enumerate over with a foreach by doing this xml.SelectNodes("//Application").
If you are having trouble with extdacting stuff though that is probably the scope of a different question since this was just about how to get the XML document loaded.
xml.DocumentElement["proxyAgent"].InnerText;
The proxyAgent element is self closing. InnerText will return the string inside of an XML element, in this case, there is no inner elements.
You need to access an attribute of the element, not the InnerText.
Try this:
string port = xml.GetElementsByTagName("ProxyAgent")[0].Attributes["listenPort"].ToString();
Or use Linq to XML:
http://msdn.microsoft.com/en-us/library/bb387098.aspx
And... your XML is not malformed...

Loading and reading XML file fails on its processing instruction

I'm stuck on a subtle problem. I try to build a C# 4.0 console application to read an XML file with.
The XML file is as follow:
<?xml version="1.0" encoding="UTF-8"?>
<?xml:stylesheet type='text/xsl' href='report.xsl' version='1.0'?>
...
<logs>
...
</logs>
And this is my code:
...
var root = XDocument.Load(xmlStream);
IEnumerable<XElement> address =
from el in root.Descendants("formated-text")
select el;
...
This gives me the following error at the Load method:
The ':' character, hexadecimal value 0x3A, cannot be included in a name. Line 2, position 6.
Changing the colon on the second line to a '-' solves the error ... duh
What can I do in my code to read the source XML without having to replace that 'stupid' colon first?
Thank you!
It looks to me like you simply have an invalid XML document. The colon should be a hyphen (as per W3C). I doubt that you'll be able to make LINQ to XML parse an invalid document - and you shouldn't try. You should fix the document instead.
The colon is wrong, you should be using the dash
See http://www.w3.org/Style/styling-XML.en.html
Nothing. That "stupid colon" is simply invalid at that position.
You XSL-Stylesheet element is incorrect.
It should be:
<?xml-stylesheet type='text/xsl' href='report.xsl' version='1.0'?>
Try validating your XML against any number of online validators.
You can try loading the XML as a string and fixing this issue using string parsing, or you could read the original file line by line and fix any occurences of xml:stylsheet before saving it like the text file in this example, but it would be better to get whomever created the XML to fix it at source.
I found out that the origin of these 'malformed' XML files dates back to the mid 1990's ... yes, such an old system is today still in use and still produces this output. I can live with a workaround in my code.
Thank you for taking time to provide some usefull clues at what was/is going on with these XML elements.
I needed this confirmation that the creator of the source XML did a mistake with that colon.
I already have implemented a plan B, until I can convince a really big department (not mine) to make the change in their application ... :o(
Plan B is to read the XML file first and replace all 'xml:' occurences. Then feed this corrected file into my process.

XML exception on loading

I have an XML file. When I try to load it using .LOAD methods, I get this exception:
System.Xml.XmlException: data at root level invalid at position 1 line 1.
What I have at the beginning of the XML file is this:
<?xml version="1.0" standalone="yes" ?>
I think that string that is used for LoadXml is constructed wrong by either
ignoring BOM and forcing wrong encoding
reading BOM as first character
constructed by hand altogether and first character is not <
Based on last comment I bet that code looks like (or some variation of it) instead of loading XML directly from Stream object (which will handle encoding properly):
// My guess of how wrong code looks like! Not a solution!!!!
StreamReader r = new StreamReader(path, System.Text.Encoding.Unicode);
string xml = r.ReadToEnd();
XmlDocument d = new XmlDocument();
d.LoadXml(xml);
You should review your code that constructs the string you are using in XmlDocument.LoadXml and check if it is indeed valid XML. I'd recommend to create small program that models code that is failing and investigate the behavior.
Position 1 line 1 suggests a problem with the very first char it encounters.
I would suggest firstly confirming that no leading whitespace/other char is in there (sounds silly, but they can creep in easily).
It could also be a char encoding issue, causing that first char to not be read as a '<'.
I bet it's not there. I've found that when I've gotten this error the file or path is missing/incorrect.
Thanks for pouring in your suggestions. The problem was on the build server, the XML file was being pulled from a field called contents in a table called File. I am accessing the XML using the FileID. But the FileID is not the same as FileID on my local database. So, On the build server, I was pulling the XML from a test record which had dummy data. Hence the error. Hope I have made sense. I have fixed the issue by dynamically finding the FileID and querying the contents.

Categories