[英]C# Serializing XmlElement with XmlText
我需要復制這種XML格式:
<item>
<attribute1>1</attribute1>
<attribute2 something="true">
2
</attribute2>
<attribute3 something="false">
3
</attribute3>
<!-- goes on until attribute25 -->
</item>
我目前正在使用這樣的東西來實現我想要的東西:
Item.cs:
[XmlType(TypeName = "item")]
public class Item {
[XmlElement("attribute1")]
public CustomElement<string> Attribute1 { get; set; }
[XmlElement("attribute2")]
public CustomElement<string> Attribute2 { get; set; }
[XmlElement("attribute3")]
public CustomElement<string> Attribute3 { get; set; }
// Etc Etc
}
CustomElement.cs:
/// <summary>
/// Represents a CustomElement.
/// </summary>
/// <typeparam name="T">The type for the value of the element.</typeparam>
public class CustomElement<T>
{
[XmlIgnore] public T Value;
[XmlText]
public T XmlValue => Value;
public CustomElement()
{
}
public CustomElement(T value)
{
Value = value;
}
[XmlIgnore]
public bool? Something { get; set; }
[XmlAttribute("something")]
public bool XmlSomething
{
get => Something != null && Something.Value;
set => Something = value;
}
public bool XmlSomethingSpecified => Something.HasValue;
public static implicit operator CustomElement<T>(T x)
{
return new CustomElement<T>(x);
}
}
但是,在序列化我的Item
我得到:
<item>
<attribute1 />
<attribute2 />
<attribute3 />
</item>
如何修復我的CustomElement
類,以便不會丟失值?
你有幾個問題:
您正在嘗試將XmlValue
成員序列化為為CustomElement<T>
實例生成的元素的元素值,但您已將其定義為只讀 表達式 - 身體成員 :
public T XmlValue => Value;
XmlSerializer
只會序列化公共讀/寫屬性和字段,因此您必須添加setter和getter:
[XmlText] public T XmlValue { get => Value; set => Value = value; }
或者,為了簡化模型,您可以完全消除XmlValue
並通過使用[XmlText]
標記來直接序列化Value
。 XML序列化屬性可以應用於字段和屬性。
您正在嘗試使用{propertyName}Specified
模式在基礎值為null
時禁止<something>
元素的序列化。 此模式主要用於跟蹤是否遇到關聯元素,因此必須使用[XmlIgnore]
標記xxxSpecified
屬性:
[XmlIgnore] public bool XmlSomethingSpecified => Something.HasValue;
或者,由於您實際上不需要跟蹤<something>
元素的存在,您可以通過切換到ShouldSerialize{PropertyName}()
模式來簡化模型:
public bool ShouldSerializeXmlSomething() => Something.HasValue;
兩個模式之間的差異在ShouldSerialize ()vs Specified Conditional Serialization Pattern中描述 。
如果您的Item
類型將是XML文檔的根元素,則必須使用[XmlRoot("item")]
標記它以使根元素的名稱為<item>
:
[XmlRoot("item")] [XmlType(TypeName = "ci")] public class Item { // Etc Etc }
在您的c#代碼中,您已使用[XmlElement]
標記了XmlSomething
屬性,但在XML中, something
內容顯示為元素 : <something>true</something>
。
如果你真的希望它是一個元素,你必須用[XmlElement]
標記XmlSomething
:
[XmlElement("something")] public bool XmlSomething { get => Something != null && Something.Value; set => Something = value; }
在您的問題中,您將顯示具有非布爾文本值的<something>
元素的示例:
<attribute3> 3 <something>text</something> </attribute3>
我認為這是問題中的拼寫錯誤,但如果沒有,您將需要重新設計您的CustomElement<T>
類型以使Something
成為string
。
樣本工作Roslyn .Net小提琴 , 第二個用於CustomElement<T>
的建議簡化, 第三個用 <something>
作為子元素出現。
來自第二小提琴的課程如下:
public class CustomElement<T>
{
[XmlText]
public T Value;
public CustomElement()
{
}
public CustomElement(T value)
{
Value = value;
}
[XmlIgnore]
public bool? Something { get; set; }
[XmlAttribute("something")]
public bool XmlSomething
{
get => Something != null && Something.Value;
set => Something = value;
}
public bool ShouldSerializeXmlSomething() => Something.HasValue;
public static implicit operator CustomElement<T>(T x)
{
return new CustomElement<T>(x);
}
}
[XmlRoot("item")]
[XmlType(TypeName = "ci")]
public class Item
{
[XmlElement("attribute1")]
public CustomElement<string> Attribute1 { get; set; }
[XmlElement("attribute2")]
public CustomElement<string> Attribute2 { get; set; }
[XmlElement("attribute3")]
public CustomElement<string> Attribute3 { get; set; }
// Etc Etc
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.