0
\$\begingroup\$

There is a need to have a specific structure of XML string when interacting with 3rd party system. Here are two examples:

<DocumentElement>
 <Country>
  <CountryCode>UA</CountryCode>
  <Name>Ukraine</Name>
 </Country>
</DocumentElement>

and

<DocumentElement>
 <Currency>
  <CurrencyCode>UAH</CurrencyCode>
  <Description>Hryvnia</Description>
 </Currency>
</DocumentElement>

Like you can see it is a common wrapping tag DocumentElement. So, here is approach #1:

Have a wrapper class:

[XmlRoot("DocumentElement")]
public class DocumentElement<T>
{
    public T InnerObject { get; set; }

    public DocumentElement(){}
    public DocumentElement(T some)
    {
        InnerObject = some;
    }
}

And replace InnerObject after conversion:

public static string GetXml<T>(T instance) where T : class
{
    var wrapper = new DocumentElement<T>(instance);
    var writer = new StringWriter();
    var serializer = new XmlSerializer(typeof(DocumentElement<T>));
    serializer.Serialize(writer, wrapper);
    return writer.ToString().Replace("InnerObject", instance.GetType().Name);
}

Or, approach #2:

Throw away DocumentElement and just concat a needed string:

public static string GetXml<T>(T instance) where T : class
{
    var writer = new StringWriter();
    var serializer = new XmlSerializer(typeof(T));
    serializer.Serialize(writer, instance);
    return "<DocumentElement>" + writer.ToString() + "</DocumentElement>";
}

Both approaches produce a needed format but neither looks clean enough. Maybe, someone can suggest a better approach to this?

\$\endgroup\$
1
\$\begingroup\$

Take a look at How to: Specify an Alternate Element Name for an XML Stream. Although it is more code, I would use the mentioned XmlAttributeOverrides like so

public static string GetXml<T>(T instance, string sourceName = "InnerObject") where T : class
{
    var wrapper = new DocumentElement<T>(instance);
    var writer = new StringWriter();
    var overrides = CreateOverrides(typeof(DocumentElement<T>), instance.GetType().Name, sourceName);

    var serializer = new XmlSerializer(typeof(DocumentElement<T>), overrides);
    serializer.Serialize(writer, wrapper);
    return writer.ToString();
}
private static XmlAttributeOverrides CreateOverrides(Type type, string destinationName, string sourceName)
{
    var elementAttribute = new XmlElementAttribute() { ElementName = destinationName };
    var attributes = new XmlAttributes();
    attributes.XmlElements.Add(elementAttribute);
    var overrides = new XmlAttributeOverrides();
    overrides.Add(type, sourceName, attributes);
    return overrides;
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.