我有一个类被序列化为 XML 以供 Web 服务使用。在此类实例中,XML 必须包含一个 CDATA 部分,以便 Web 服务读取它,但我不知道如何实现它。
XML 需要如下所示:
<UpdateOrderStatus>
<Action>2</Action>
<Value>
<![CDATA[
<Shipment>
<Header>
<SellerID>
...
]]>
</Value>
</UpdateOrderStatus>
我能够生成适当的 XML,除了 CDATA 部分。
我的班级结构如下:
public class UpdateOrderStatus
{
public int Action { get; set; }
public ValueInfo Value { get; set; }
public UpdateOrderStatus()
{
Value = new ValueInfo();
}
public class ValueInfo
{
public ShipmentInfo Shipment { get; set; }
public ValueInfo()
{
Shipment = new ShipmentInfo();
}
public class ShipmentInfo
{
public PackageListInfo PackageList { get; set; }
public HeaderInfo Header { get; set; }
public ShipmentInfo()
{
PackageList = new PackageListInfo();
Header = new HeaderInfo();
}
....
我已经看到了一些关于使用的建议:
[XmlElement("node", typeof(XmlCDataSection))]
但这会导致异常
我也试过
[XmlElement("Value" + "<![CDATA[")]
但生成的 XML 显示不正确
<Value_x003C__x0021__x005B_CDATA_x005B_>
....
</Value_x003C__x0021__x005B_CDATA_x005B_>
谁能告诉我我做错了什么,或者我需要去哪里?
- 编辑 -
使每个 carlosfigueira 的 shippingInfo 可序列化在大多数情况下都有效,但是我得到了额外的?生成的 XML 中的字符(有关详细信息,请参阅使用 XmlWriterSettings 和 XmlSerializer 编写 XML 片段的帖子给出了额外的字符)
因此,我将 Write XML 方法更改为:
public void WriteXml(XmlWriter writer)
{
using (MemoryStream ms = new MemoryStream())
{
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", "");
XmlWriterSettings settings = new XmlWriterSettings();
settings.OmitXmlDeclaration = true;
settings.Encoding = new UnicodeEncoding(bigEndian: false, byteOrderMark: false);
settings.Indent = true;
using (XmlWriter innerWriter = XmlWriter.Create(ms, settings))
{
shipmentInfoSerializer.Serialize(innerWriter, this.Shipment,ns);
innerWriter.Flush();
writer.WriteCData(Encoding.UTF8.GetString(ms.ToArray()));
}
}
}
但是我没有例外:
System.InvalidOperationException: There was an error generating the XML document. ---> System.ArgumentException: '.', hexadecimal
value 0x00, is an invalid character.
- 编辑 -
该异常是由于包含了我之前的 serializeToString 方法引起的。由于删除 CDATA 输出是正确的,除了间距问题,但我还得到了应由指定的 XML 设置删除的命名空间和 xml 声明。输出是:
<?xml version="1.0"?>
<UpdateOrderStatus xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Action>1</Action>
<Value><![CDATA[< S h i p m e n t I n f o >
< P a c k a g e L i s t >
< P a c k a g e >
< S h i p D a t e > 2 0 1 2 - 0 7 - 1 3 T 1 1 : 5 8 : 5 1 . 0 9 2 5 6 1 5 - 0 4 : 0 0 < / S h i p D a t e >
< I t e m L i s t >
< I t e m >
< S h i p p e d Q t y > 0 < / S h i p p e d Q t y >
< / I t e m >
< / I t e m L i s t >
< / P a c k a g e >
< / P a c k a g e L i s t >
< H e a d e r >
< S e l l e r I d > S h i p m e n t h e a d e r < / S e l l e r I d >
< S O N u m b e r > 0 < / S O N u m b e r >
< / H e a d e r >
< / S h i p m e n t I n f o > ]]></Value>
</UpdateOrderStatus>
使用新类避免 BOM 的任何想法?
--编辑 3 --成功!
我已经实现了下面建议的更改,现在具有以下编写器类和测试方法:
UpdateOrderStatus obj = new UpdateOrderStatus();
obj.Action = 1;
obj.Value = new UpdateOrderStatus.ValueInfo();
obj.Value.Shipment = new UpdateOrderStatus.ValueInfo.ShipmentInfo();
obj.Value.Shipment.Header.SellerId = "Shipment header";
obj.Value.Shipment.PackageList = new UpdateOrderStatus.ValueInfo.ShipmentInfo.PackageListInfo();
obj.Value.Shipment.PackageList.Package = new UpdateOrderStatus.ValueInfo.ShipmentInfo.PackageListInfo.PackageInfo();
obj.Value.Shipment.PackageList.Package.ShipDate = DateTime.Now;
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", "");
XmlWriterSettings settings = new XmlWriterSettings();
settings.OmitXmlDeclaration = true;
settings.Encoding = new UTF8Encoding(false);
settings.Indent = true;
XmlSerializer xs = new XmlSerializer(typeof(UpdateOrderStatus));
MemoryStream ms = new MemoryStream();
XmlWriter writer = XmlWriter.Create(ms, settings);
xs.Serialize(writer, obj, ns);
Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray()));
}
public void WriteXml(XmlWriter writer)
{
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", "");
XmlWriterSettings settings = new XmlWriterSettings();
settings.OmitXmlDeclaration = true;
settings.Indent = true;
StringBuilder sb = new StringBuilder();
using (XmlWriter innerWriter = XmlWriter.Create(sb, settings))
{
shipmentInfoSerializer.Serialize(innerWriter, this.Shipment, ns);
innerWriter.Flush();
writer.WriteCData(sb.ToString());
}
}
这将生成以下 XML:
<UpdateOrderStatus>
<Action>1</Action>
<Value><![CDATA[<ShipmentInfo>
<PackageList>
<Package>
<ShipDate>2012-07-13T14:05:36.6170802-04:00</ShipDate>
<ItemList>
<Item>
<ShippedQty>0</ShippedQty>
</Item>
</ItemList>
</Package>
</PackageList>
<Header>
<SellerId>Shipment header</SellerId>
<SONumber>0</SONumber>
</Header>
</ShipmentInfo>]]></Value>
</UpdateOrderStatus>