有没有办法让XmlSerializer
将原始类成员(例如字符串属性)序列化为XML属性,而不是XML元素,不必须写入[XmlAttribute]
每个属性声明的前面?
即是否有一个全局开关告诉XmlSerializer
将所有基本类成员序列化为XML属性?
假设我们有以下课程:
public class Person
{
public string FirstName
{
...
}
public string LastName
{
...
}
}
然后XmlSerializer
默认生成此代码:
<Person>
<FirstName>John</FirstName>
<LastName>Doe</LastName>
</Person>
然而,我想要的是这段代码:
<Person FirstName="John" LastName="Doe"/>
再说一遍:我想在没有[XmlAttribute]
(或没有XmlAttributeOverrides
的情况下做到这一点,这会更有效。)
一种可能的解决方案是使用通用后处理步骤,该步骤应用XSLT转换将元素转换为属性。但我想知道是否有更简单的解决方案。
答案 0 :(得分:4)
实现此目的的一种方法是在实现IXmlSerializable接口的基类中实现序列化逻辑。要序列化为XML的类必须从此基类派生才能获得功能。
这是一个例子
public class XmlSerializableEntity : IXmlSerializable
{
public XmlSchema GetSchema()
{
// Implementation omitted for clarity
}
public void ReadXml(XmlReader reader)
{
// Implementation omitted for clarity
}
public void WriteXml(XmlWriter writer)
{
var properties = from property in this.GetType().GetProperties()
where property.PropertyType.IsPrimitive ||
property.PropertyType == typeof(string)
select property;
foreach (var property in properties)
{
var name = property.Name;
var value = property.GetValue(this, null).ToString();
writer.WriteAttributeString(name, value);
}
}
}
这里我们使用Reflection从当前对象获取属性列表,其类型是基元或String。然后使用提供的XmlWriter对象将这些属性作为属性写入XML输出。
要序列化的类只需继承XmlSerializableEntity
即可自动获取此行为:
[Serializable]
public class Foo : XmlSerializableEntity
{
public int Bar { get; set; }
}
答案 1 :(得分:0)
我认为Xslt是最稳定,易于维护和优雅的方式。 它不需要重新设置所有东西, 依赖于已经测试过的序列化, 允许在类中使用xml自定义属性, 并且可以通过编译变换在内存中完成。
这是一些应该这样做的通用xslt:
<?xml version=’1.0′ encoding=’utf-8′?>
<xsl:stylesheet version=’1.0′ xmlns:xsl=’http://www.w3.org/1999/XSL/Transform’ xmlns:msxsl=’urn:schemas-microsoft-com:xslt’ exclude-result-prefixes=’msxsl’>
<xsl:template match=’*'>
<xsl:copy>
<xsl:for-each select=’@*|*[not(* or @*)]‘>
<xsl:attribute name=’{name(.)}’><xsl:value-of select=’.'/>
</xsl:attribute>
</xsl:for-each>
<xsl:apply-templates select=’*[* or @*]|text()’/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
话虽如此,我想知道元素是否比属性慢,尤其是在线路上发送时。