我有一个类被序列化为XML供Web服务使用。在这个类的实例中,XML必须包含CDATA部分以供Web服务读取,但是我对如何实现这一点不知所措。将类序列化为XML并包含CDATA段时的问题
的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 shipmentInfo序列化工作的大部分,但我得到额外的?在生成的XML字符(请参阅发布Writing an XML fragment using XmlWriterSettings and XmlSerializer is giving an extra character了解详细信息)
因此我改变了写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 - SUCCESS!
我已经实现了以下建议的修改,现在有下列作家类和测试方法:
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>
请注意,CDATA节是一种转义xml的方式,使其更具可读性。 CDATA的内容不是Xml。 <![CDATA [ ]]>是<测试/ >的等效如果您是确保内容始终是你应该能够预先处理文件删除CDATA有效的XML文档和反转义CDATA节的内容。请注意,如果内容无效,Xml将使整个文档无效。另一个选择是如下所述实现IXmlSerializable,但一旦启动它将会增长并且难以维护。 –
Pawel
2012-07-13 16:44:08