Click here to Skip to main content
15,891,763 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I want a way to serialise generic objects into XML fragments.

The fragments will be inserted into other XML documents and as such, I require a result that would look something like:

XML
<firstProperty>firstPropertyValue</firstProperty>
<secondProperty>secondPropertyValue</secondProperty>


as opposed to:

XML
<className xlmns="Whatever">
    <firstProperty>firstPropertyValue</firstProperty>
    <secondProperty>secondPropertyValue</secondProperty>
</className>


My code looks like this:

C#
private static string GetRow<T>(object _data)
{
    StringBuilder xml = new StringBuilder();

    T data = (T)_data;

    XmlWriterSettings settings = new XmlWriterSettings();

    settings.OmitXmlDeclaration = true;
    settings.ConformanceLevel = ConformanceLevel.Fragment;

    XmlSerializer serialiser = new XmlSerializer(typeof(T));
    XmlWriter writer = XmlWriter.Create(xml, settings);

    serialiser.Serialize(writer, data, null);

    return xml.ToString();

}


My first thought was that the OmitXmlDeclaration setting would do the job - it doesn't unless you set ConformanceLevel to Fragment. The problem is, once I do set the ConformanceLevel, I get the following run-time error:

"
Quote:
"WriteStartDocument cannot be called on writers created with ConformanceLevel.Fragment."


So it would appear that XmlSerializer.Serialize() is calling WriteStartDocument regardless of ConformanceLevel being set to Fragment rather than Document.

I suspect that the easiest way around this will be to write my own serialiser but I'd be interested to know if there is actually a way of successfully producing a fragment from the XmlSerializer class.
Posted
Updated 6-Apr-20 7:04am

string FragmentXml(object o) {
    var doc = new XmlDocument();
    using var writer = doc.CreateNavigator().AppendChild();
    new XmlSerializer(o.GetType()).Serialize(writer, o);
    return doc.DocumentElement.InnerXml;
}
 
Share this answer
 
If your issue is just to get the fragment. One way of doing this is:

var reader = XmlReader.Create(YOUR_SERIALIZED_FILE_NAME);
reader.Read();
reader.ReadToFollowing(NODE_NAME);

Then use either reader.ReadOuterXml() or reader.ReadInnerXml() as per ur requirement.

Hope this would help.
 
Share this answer
 
Comments
PeejayAdams 15-Dec-14 10:47am    
That was the inspiration I needed, thank you!

I've changed my code to attach an XmlReader to the XmlWriter's FileStream and it does just what I want:

private static string GetRow<t>(object _data)
{
StringBuilder xml = new StringBuilder();
MemoryStream stream = new MemoryStream();

T data = (T)_data;

XmlSerializer serialiser = new XmlSerializer(typeof(T));

XmlWriter writer = XmlWriter.Create(stream);

serialiser.Serialize(writer, data, null);
writer.Close();

stream.Seek(0, SeekOrigin.Begin);

XmlReader xmlReader = XmlReader.Create(stream);

xmlReader.MoveToContent();

return xmlReader.ReadInnerXml();
}

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900