如何在序列化时添加ENTITY?

时间:2017-05-26 01:03:16

标签: c# xml xsd

问题

我可以修改我的POCO类,以便在序列化时它们包含所需的ENTITY吗?在阅读this from W3Cthis answer to a similar question后,我意识到我的XML应该包含DOCTYPE,如下所示,我只是不知道如何插入它。

<?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>

我的序列化代码如下所示

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

背景

我使用XmlSerializerStringWriter将我的根类序列化为字符串,然后使用this post中的XmlValidator验证XML字符串。在验证XML时验证器说......

  

参考未申报的实体,&#39; NZ&#39;。在第37行第24位

...引用此元素的ISO3166属性

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

......定义为:

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

我的目的是将值范围限制为NZAU。我可以像这样添加DOCTYPE,但显然我更愿意找到更好的方法:

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

XML根类的定义(由xsd.exe生成并手动调整以添加noNamespaceSchemaLocation)是

[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.
}

2 个答案:

答案 0 :(得分:0)

我稍微更改了序列化,因此根据this answer包含了XmlWriter

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;
    }
}

答案 1 :(得分:0)

您需要添加设置

            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            XmlWriter writer = XmlWriter.Create(sww, settings);