tags:

views:

56

answers:

2

Hi, 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!!

A: 

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.

MainMa
Thanks very much for the quick response.The second option seems very interesting to me; the class created for the XSD Schema is called myFields; so I have a WebMethod called SubmitForm which uses an instance "newForm" of this class.How do I create the XmlTextWriter instance with this?Sorry if this seems stupid, but this is the first time (and maybe even last) that I am using .NET and XML. I just have some vague notions and I am doing this by searching everything on Google :D.
Yusuf
OK, I've been able to create the XmlTextWriter instance, and I've even written the PI; however it appends the PI at the end of the file, when it should have been at the top.I must say that I first created a TextWriter instance from the file I already created, then an XmlTextWriter instance from that one.
Yusuf
If it appends the PI, it probably means that you are calling `WriteProcessingInstruction` after you serialize the object. If so, call it *before* serialization.
MainMa
I tried it; the PI's are in fact written at the top, but it goes before the XML declaration, and makes it unreadable my InfoPath.I have this: `XmlSerializer ser = new XmlSerializer(newForm.GetType());` `Stream stream = new FileStream(fileName, FileMode.Append, FileAccess.Write, FileShare.None);` `ser.Serialize(stream, newForm);` `stream.Close();` Is there any way I can modify the **stream** to put the PI's there? Because it seems that the whole structure is already generated in that stream..
Yusuf
You can use a following workaround: include the three lines with `WriteProcessingInstruction` (ie. including the XML declaration), and use something like this: http://stackoverflow.com/questions/933664/net-xml-serialization-without-xml-root-node/955612#955612. It must be a more appropriate way to do things, but I can't figure out how to do it so fast.
MainMa
Let's say I've been able to create an `XmlDocument` instance with the file. Can you now show me how to add the PI's please?
Yusuf
If you have an instance of `XmlDocument`, use `XmlDocument.CreateProcessingInstruction` (follow the first link in my answer for further information). Then save your document with `XmlDocument.Save` method.
MainMa
Yep, that's what I did finally, the `CreateProcessingInstruction` returns a node that must then be inserted in the `XmlDocument`.Thanks very much for your help!!
Yusuf
+1  A: 

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.

dahlbyk
Finally I came to using this solution in fact, but I still have the problem of the PI's getting put before the `<?xml...` itself.. :(
Yusuf