웹 서비스에서 사용하기 위해 XML로 직렬화되는 클래스가 있습니다. 이 클래스 인스턴스에서 XML은 웹 서비스가 읽을 수있는 CDATA 섹션을 포함해야하지만이를 구현하는 방법에 대한 손실이 있습니다.클래스를 XML로 직렬화하고 CDATA 섹션을 포함하는 문제가 발생했습니다.
<UpdateOrderStatus>
<Action>2</Action>
<Value>
<![CDATA[
<Shipment>
<Header>
<SellerID>
...
]]>
</Value>
</UpdateOrderStatus>
내가 CDATA 부분을 제외하고, 해당 XML을 생성 할 수 있어요 :
XML은 같이 할 필요가있다.
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가 직렬화하기
--Edit--
그러나 내가 추가 취득, 대부분의 경우 작동? 결과 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 - 성공!
나는 변화가 아래에 제시 이제 다음과 같은 작가 클래스와 테스트 방법이 구현 :
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이 아닙니다. 은 < 테스트와 일치합니다./> 내용이 항상 유효한 Xml 문서라고 확신하는 경우 문서를 사전 처리하여 CDATA를 제거하고 CDATA 섹션의 내용을 이스케이프 처리 할 수 있어야합니다 . 내용이 유효한 Xml이 아니면 전체 문서가 유효하지 않게됩니다. 또 다른 옵션은 아래에 설명 된대로 IXmlSerializable을 구현하는 것입니다. 일단 시작하면 확장되고 유지 관리가 어려울 수 있습니다. – Pawel