0

Question

Can I modify my POCO classes so that when serialised they contain the ENTITYs required? After reading this from W3C and this answer to a similar question I realised my XML should contain the DOCTYPE as below, I just don't know how to insert it.

<?xml version="1.0" encoding="utf-16"?>
<!DOCTYPE documentElement[<!ENTITY NZ "NZ"><!ENTITY AU "AU">]>
<ValuationTransaction xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://vx.valex.com.au/lixi/schema/1.3.5/ValuationTransaction.xsd" ProductionData="Yes">
    ... etc.
</ValuationTransaction>

My serialising code looks like this

public static string ToXmlString(this ValuationTransaction payloadPoco)
{
    var stringwriter = new StringWriter();
    var serializer = new XmlSerializer(payloadPoco.GetType());
    serializer.Serialize(stringwriter, payloadPoco);
    return stringwriter.ToString();
}

Background

I'm serialising my root class to a string using an XmlSerializer and a StringWriter, then validating the XML string using an XmlValidator from this post. While validating the XML the validator says...

Reference to an undeclared entity, 'NZ'. at line 37 position 24

... which refers to the ISO3166 attribute of this element

<Country ISO3166="NZ">NEW ZEALAND</Country>

... the definition for which is:

[System.Xml.Serialization.XmlAttributeAttribute(DataType = "ENTITY")]
public string ISO3166
{
    get { return this.iSO3166Field; }
    set { this.iSO3166Field = value; }
}

The range of values is limited for my purposes to NZ and AU. I can add the DOCTYPE like this, though obviously I'd rather find a better way:

var entitiesDtd = @"<!DOCTYPE documentElement[<!ENTITY NZ ""NZ""><!ENTITY AU ""AU"">]>" + Environment.NewLine;
xmlString = xmlString.Insert(xmlString.IndexOf("<ValuationTransaction"), entitiesDtd);

The definition for the XML root class (generated by xsd.exe and manually tweaked to add noNamespaceSchemaLocation) is

[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class ValuationTransaction
{
    [XmlAttribute("noNamespaceSchemaLocation", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
    public string noNamespaceSchemaLocation = "https://vx.valex.com.au/lixi/schema/1.3.5/ValuationTransaction.xsd";
    ... etc.
}
OutstandingBill
  • 2,614
  • 26
  • 38

2 Answers2

0

I changed my serialisation a little so that it included an XmlWriter as per this answer.

XmlSerializer xsSubmit = new XmlSerializer(typeof(ValuationTransaction));
var subReq = payloadPoco;
var xml = "";

using (var sww = new StringWriter())
{
    var writerSettings = new XmlWriterSettings();
    writerSettings.Indent = true;

    using (XmlWriter writer = XmlWriter.Create(sww, writerSettings))
    {
        writer.WriteDocType("documentElement", null, null, "<!ENTITY AU \"Australia\"><!ENTITY NZ \"New Zealand\">");
        xsSubmit.Serialize(writer, subReq);
        xml = sww.ToString(); // Your XML
        return xml;
    }
}
OutstandingBill
  • 2,614
  • 26
  • 38
0

You need to add settings

            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            XmlWriter writer = XmlWriter.Create(sww, settings);
jdweng
  • 33,250
  • 2
  • 15
  • 20
  • Thanks - I was just finding that out as you wrote. Not sure if by itself that works as an answer to the question though. – OutstandingBill May 26 '17 at 04:53
  • You are missing a namespace NZ. Should have xmlns:NZ some place in the xml. – jdweng May 26 '17 at 05:00
  • The validator seems happy without a namespace on the entity, and the example on [this MSDN page](https://msdn.microsoft.com/en-us/library/system.xml.xmlwriter.writedoctype(v=vs.110).aspx) doesn't have one. Could you show your reasoning why a namespace might be required? – OutstandingBill May 26 '17 at 08:50
  • Does it work if you remove : [System.Xml.Serialization.XmlAttributeAttribute(DataType = "ENTITY")] – jdweng May 26 '17 at 09:24