5

Giả sử một XML như thế này:Deserialize giá trị phần tử như chuỗi mặc dù nó có chứa nội dung hỗn hợp

<my:Root xmlns:my="http://foo/bar"> 
    <my:FieldBasic>content</my:FieldBasic> 
    <my:FieldComplex> 
     <html xml:space="preserve" xmlns="http://www.w3.org/1999/xhtml"> 
      <div><h1>content</h1></div> 
     </html> 
    </my:FieldComplex> 
<my:Root> 

và một lớp học như:

[Serializable] 
[XmlType(AnonymousType = true, Namespace = "http://foo/bar")] 
[XmlRoot(ElementName = "Root", Namespace = "http://foo/bar", IsNullable = false)] 
public class MyRoot 
{ 
    public string FieldBasic { get; set; } 
    public string FieldComplex { get; set; } 
} 

Làm thế nào để deserialize <my:FieldComplex> thành một chuỗi trong FieldComplex? Nó không thành công khi nó tìm thấy HTML bên trong. Tôi muốn làm cho nó cho tôi một chuỗi với nội dung này:

<html xml:space="preserve" xmlns="http://www.w3.org/1999/xhtml"> 
    <div><h1>content</h1></div> 
</html> 

Nếu Tôi tuyên bố FieldComplex như public object FieldComplex (ví dụ: xsd:anyType) nó kinda hoạt động và tôi nhận được một XMLNode[] bên trong mà tôi có thể sử dụng.

Nhưng tôi cần FieldComplex là kiểu chuỗi cho serialization như đối với serialization XML sẽ không chứa HTML, nó sẽ như thế nào:

<my:Root xmlns:my="http://foo/bar"> 
    <my:FieldBasic>content</my:FieldBasic> 
    <my:FieldComplex>content</my:FieldComplex> 
<my:Root> 

Tuyên bố FieldComplex như đối tượng sẽ chèn những thuộc tính trên <my:FieldComplex> phần tử:

xmlns:q1="http://www.w3.org/2001/XMLSchema" p3:type="q1:string" xmlns:p3="http://www.w3.org/2001/XMLSchema-instance 

và tôi không muốn điều đó. Tôi cũng không muốn sử dụng các lớp khác nhau cho serialization và deserialization.

Vì vậy, có thể không?

Để thực hiện một câu chuyện dài ngắn, là nó có thể có lớp này:

public class MyRoot 
{ 
    public string FieldBasic { get; set; } 
    public string FielComplex { get; set; } 
} 

Serialize này:

<my:Root xmlns:my="http://foo/bar"> 
    <my:FieldBasic>content</my:FieldBasic> 
    <my:FieldComplex>content</my:FieldComplex> 
<my:Root> 

và deserialize từ này:

<my:Root xmlns:my="http://foo/bar"> 
    <my:FieldBasic>content</my:FieldBasic> 
    <my:FieldComplex> 
     <html xml:space="preserve" xmlns="http://www.w3.org/1999/xhtml"> 
      <div><h1>content</h1></div> 
     </html> 
    </my:FieldComplex> 
<my:Root> 

?

P.S. Chỉ cần giải thích "tại sao?". Tôi có một phù thủy lớp được tuần tự hóa. XML được tuần tự hóa sau đó di chuyển qua nhiều nút trong ứng dụng và cuối cùng quay trở lại nhưng thay đổi như trên. Các lớp thực hiện một số xác thực XML và có các thuộc tính hoặc các phần tử phụ thêm vào đầu vào không thực hiện được việc xác nhận và dừng luồng. Tôi muốn ánh xạ XML trả về cho cùng một lớp. Nội dung chỉ là chuỗi từ nó quan điểm nhưng tất nhiên không giống nhau cho serialization/deserialization :(

Trả lời

3

Điều này không hoàn toàn hoàn thành vì tôi không thể nhớ nếu bạn có thể/làm thế nào để thêm tiền tố không gian tên cho phần tử gốc trong Xml Serialization.Nhưng nếu bạn thực hiện các giao diện IXmlSerializable trong lớp MyRoot của bạn như thế này:

[XmlRoot("Root", Namespace="http://foo/bar")] 
public class MyRoot : IXmlSerializable 

Sau đó viết các phương pháp serialization XML chính mình, một cái gì đó như thế này:

 void IXmlSerializable.ReadXml(System.Xml.XmlReader reader) 
     { 
      reader.MoveToContent(); 
      var outerXml = reader.ReadOuterXml(); 
      XElement root = XElement.Parse(outerXml); 

      this.FieldBasic = root.Elements(XName.Get("FieldBasic", "http://foo/bar")).First().Value; 
      this.FieldComplex = root.Elements(XName.Get("FieldComplex", "http://foo/bar")).First().Elements().First().Value.Trim(); 
     } 



     void IXmlSerializable.WriteXml(System.Xml.XmlWriter writer) 
     { 
      writer.WriteRaw(String.Format("\r\n\t<my:FieldBasic>\r\n\t\t{0}\r\n\t</my:FieldBasic>", this.FieldBasic)); 
      writer.WriteRaw(String.Format("\r\n\t<my:FieldComplex>\r\n\t\t{0}\r\n\t</my:FieldComplex>\r\n", this.FieldComplex)); 
     } 

(Return null từ phương pháp GetSchema)

Điều này sẽ giúp bạn có được ít nhất là khá gần với những gì bạn đang sau.

Bạn cũng có thể thấy các liên kết này hữu ích.

IXmlSerializable

Namespaces

+0

Cảm ơn bạn rất nhiều vì giải pháp này :). Điều này thật đúng với gì mà tôi đã tìm kiếm. – Beniamin

3

Bạn có thể sử dụng CDATA trong XML để cho biết rằng nội dung là một chuỗi chữ:

<my:Root xmlns:my="http://foo/bar"> 
    <my:FieldBasic>content</my:FieldBasic> 
    <my:FieldComplex> 
    <![CDATA[ 
     <html xml:space="preserve" xmlns="http://www.w3.org/1999/xhtml"> 
     <div><h1>content</h1></div> 
     </html> 
    ]]> 
    </my:FieldComplex> 
</my:Root> 
+1

Đáng tiếc là tôi có quyền kiểm soát chỉ vào những gì được vào dòng chảy, không phải những gì được ra khỏi. Tôi không thể thêm . – JohnDoDo