views:

349

answers:

1

I have to create an XML file with all the elements prefixed, like this:

<ps:Request num="123" xmlns:ps="www.ladieda.com">
   <ps:ClientId>5566</ps:ClientId>
<ps:Request>

When i serialize my object, c# is smart and does this:

<Request num="123" xmlns="www.ladieda.com">
   <ClientId>5566</ClientId>
<Request>

That is good, because the ps: is not necessary.

But is there a way to force C# to serialize all the prefixes?

My serialize code is this (for incoming object pObject):

String XmlizedString = null;
MemoryStream memoryStream = new MemoryStream();
XmlSerializer xs = new XmlSerializer(pObject.GetType());
XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);

xs.Serialize(xmlTextWriter, pObject);
memoryStream = (MemoryStream)xmlTextWriter.BaseStream;
XmlizedString = UTF8ByteArrayToString(memoryStream.ToArray());
return XmlizedString;


private String UTF8ByteArrayToString(Byte[] characters)
{
    UTF8Encoding encoding = new UTF8Encoding();
    String constructedString = encoding.GetString(characters);
    return (constructedString);
}
+3  A: 

First of all, if the consumer of your string were processing XML, then they wouldn't care about the prefix, since it doesn't matter (to XML). Perhaps they don't understand XML, and think they're processing a string (which might need to have the string "ps:" on every element).

Second of all, you should change your code a bit:

XmlSerializer xs = new XmlSerializer(pObject.GetType());
using (MemoryStream memoryStream = new MemoryStream())
{
    XmlWriterSettings settings = new XmlWriterSettings()
    {
        Encoding = Encoding.UTF8
    };
    using (XmlWriter writer = XmlWriter.Create(memoryStream, settings))
    {
        xs.Serialize(writer, pObject);
    }
    return Encoding.UTF8.GetString(memoryStream.ToArray());
}

This will properly dispose of the stream and XmlWriter if an exception is thrown, stops using the deprecated XmlTextWriter class, and yet still returns a string containing XML written for UTF-8.

Finally, to control the prefix, see "How to: Qualify XML Element and XML Attribute Names":

XmlSerializerNamespaces myNamespaces = new XmlSerializerNamespaces();
myNamespaces.Add("ps", "www.ladieda.com");

XmlSerializer xs = new XmlSerializer(pObject.GetType());
using (MemoryStream memoryStream = new MemoryStream())
{
    XmlWriterSettings settings = new XmlWriterSettings()
    {
        Encoding = Encoding.UTF8
    };
    using (XmlWriter writer = XmlWriter.Create(memoryStream, settings))
    {
        xs.Serialize(writer, pObject, myNamespaces);
    }
    return Encoding.UTF8.GetString(memoryStream.ToArray());
}
John Saunders
+1 excellent answer - great explanations and good, easy-to-follow code samples.
marc_s
Great! This works out of the box! Thanks mate.
Michel
Very weird: this code produces a (in the debugger) non visible character as first character of the xml string.It only pops up if you compare it with the same string without this character, or if you html.encode it, because the non-visible character does get encoded. It's only 1 char, and the workaround so far is to strip it off.
Michel
Interesting. That's probably a UTF-8 Byte Order Mark (BOM).
John Saunders