[英]XML Attribute on Plain String
我想用 C# 代码生成一些 XML,如下所示。
<card>
<name>Cool Card</name>
<set rarity="common">S1</set>
</card>
我有这样的东西。
public class card
{
public string name = "Cool Card";
[XmlAttribute]
public string rarity = "common";
public string set = "S1";
}
public static void WriteXml()
{
var serializer = new XmlSerializer(typeof(card));
var myCard = new();
using var sw = new StringWriter();
serializer.Serialize(sw, myCard);
XDocument doc = XDocument.Parse(sw.ToString());
XmlWriterSettings xws = new();
xws.OmitXmlDeclaration = true;
xws.Indent = true;
using var xw = XmlWriter.Create(path, xws);
doc.Save(xw);
}
问题是这不会将“稀有度”属性添加到“设置”值。 尝试添加[XmlAttribute]会将其添加到父元素而不是下一个同级元素,我无法弄清楚如何在普通字符串元素上获取它,所以目前我的 output 看起来像。
<card rarity="common">
<name>Cool Card</name>
<set>S1</set>
</card>
XML 示例文档显示了如何在元素上设置属性的示例,但只有一个具有嵌套字段,而不是一个纯字符串。 是否可以像我第一个发布的示例演示的那样向 XML 中的普通旧字符串元素添加属性?
在这种情况下,最干净的选择是实施 IXmlSerializable:
public class card : IXmlSerializable
{
public string name = "Cool Card";
public string rarity = "common";
public string set = "S1";
public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
}
public void ReadXml(System.Xml.XmlReader reader)
{
reader.ReadStartElement(nameof(card));
while (reader.NodeType != System.Xml.XmlNodeType.EndElement)
{
if (reader.Name == nameof(name))
{
this.name = reader.ReadElementContentAsString();
}
else if (reader.Name == nameof(set))
{
this.rarity = reader.GetAttribute(nameof(rarity));
this.set = reader.ReadElementContentAsString();
}
}
reader.ReadEndElement();
}
public void WriteXml(System.Xml.XmlWriter writer)
{
writer.WriteElementString(nameof(name), this.name);
writer.WriteStartElement(nameof(set));
writer.WriteAttributeString(nameof(rarity), this.rarity);
writer.WriteString(this.set);
writer.WriteEndElement();
}
}
如果你的 class 很大,你只需要在 XML 中做一点改变,有时实现 IXmlSerializable 就是一团糟(你必须保存所有属性,只保存一两个属性,做一点改变)。 在这些情况下,您可以使用属性和一些小的助手类来获得相同的结果。 这个想法是告诉 XML 序列化器不序列化某些属性并使用另一个假属性来进行序列化。
例如,使用所需的 XML 结构创建一个 Set class:
public class XmlSet
{
private readonly card _card;
public XmlSet()
{
this._card = new card();
}
public XmlSet(card card)
{
this._card = card;
}
[XmlText]
public string set
{
get { return this._card.set; }
set { this._card.set = value; }
}
[XmlAttribute]
public string rarity
{
get { return this._card.rarity; }
set { this._card.rarity = value; }
}
}
它只是一个包装器,具有您想要的 XML 属性。 您从card
object 获取/设置值。
然后,在你的卡 class 中,忽略设置属性并序列化假属性:
public class card
{
public string name = "Cool Card";
[XmlIgnore]
public string rarity = "common";
[XmlIgnore]
public string set = "S1";
// Added to serialization
private XmlSet _xmlSetNode;
[XmlElement("set")]
public XmlSet XmlSet
{
get
{
this._xmlSetNode = this._xmlSetNode ?? new XmlSet(this);
return this._xmlSetNode;
}
set { this._xmlSetNode = value; }
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.