gpt4 book ai didi

c# - 将类序列化为 XML 并包含 CDATA 部分时出现问题

转载 作者:数据小太阳 更新时间:2023-10-29 02:49:08 29 4
gpt4 key购买 nike

我有一个序列化为 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 的 shipmentInfo 可序列化在大多数情况下都有效,但是我得到额外的 ?结果 XML 中的字符(有关详细信息,请参阅帖子 Writing an XML fragment using XmlWriterSettings and XmlSerializer is giving an extra character)

因此,我将 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 输出是正确的,除了间距问题,但我也得到了一个 namespace 和 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>

最佳答案

针对您在编辑后看到的“空格”,这是因为您使用的编码(Unicode,每个字符 2 个字节)。

尝试:

settings.Encoding = new Utf8Encoding(false);

编辑:

另请注意,MemoryStream 的格式不一定是有效的 UTF-8 编码字符串!您可以使用 StringBuilder 而不是 MemoryStream 来创建您的内部编写器。

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

关于c# - 将类序列化为 XML 并包含 CDATA 部分时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11471676/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com