XmlSerializer:将类属性序列化为自定义子元素的属性

Kon*_*ski 5 c# xml serialization xml-serialization

我正在使用XmlSerializer.我的课:

[Serializable]
[XmlRoot(ElementName="MyClass")]
public class MyClass
{
    public string Value;
}
Run Code Online (Sandbox Code Playgroud)

我想序列化它,以便Value最终成为名为(例如)"Text"的子元素的属性.

期望的结果:

<MyClass>
    <Text Value="3"/>
</MyClass>
Run Code Online (Sandbox Code Playgroud)

但是NOT(这将标记Value作为一种效果XmlAttribute)

<MyClass Value="3">
</MyClass>
Run Code Online (Sandbox Code Playgroud)

不是(这将标记价值作为一种效果XmlElement):

<MyClass>
    <Value>3</Value>
</MyClass>
Run Code Online (Sandbox Code Playgroud)

我该如何实现这一目标?

我知道我可以将Value字符串的类型更改为另一个可序列化的自定义类.

不幸的是,我有很多这样的属性,所以我需要创建几十个小类.

有没有更快的解决方案?


编辑:

回应你的意见:

  • 不,并非每个属性都必须序列化为名为"Text"的子元素.Subelement的名称是独特且明确的.

  • 示例输出XML:

    <visibility>
        <site visible="yes"/>
        <comparator visible="no"/>
        <expiration days="7"/>
        <comment>blahblahblah</comment>
    <visibility>
    
    Run Code Online (Sandbox Code Playgroud)
  • 样本类:

!

[XmlRoot(ElementName="Visibility")]
public class Visibility
{
    [XPath("/site@visible")] // if only this was possible!
    public string OnSite
    {
        get { return SiteVisible ? "yes" : "no"; }
    }

    [XPath("/comparator@visible")] // as above...
    public string InComparator
    {
        get { return ComparatorVisible ? "yes" : "no"; }
    }

    [XmlIgnore]
    public bool SiteVisible;
    [XmlIgnore]
    public bool ComparatorVisible;

    [XPath("/expiration@days")] // as above...
    public int ExpiresAfterDays; 

    [XmlElement("comment")] // this is easy
    public string Comment;
}
Run Code Online (Sandbox Code Playgroud)

Mas*_*ini 4

如果不改变类型,Value我认为这是不可能的。XmlElement(ElementName="Text")您可以添加该属性,Value但您将获得与此类似的结果:

<MyClass> 
    <Text>3</Text> 
</MyClass> 
Run Code Online (Sandbox Code Playgroud)

编辑: 另一种解决方案可能涉及 XSLT 转换:您可以使用 .Net 序列化生成 xml,然后应用 xml 转换。

XslTransform myXslTransform = new XslTransform();
myXslTransform.Load(xsltDoc);
myXslTransform.Transform(sourceDoc, resultDoc);
Run Code Online (Sandbox Code Playgroud)

我的例子的改造应该是这样的:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
    <root>
        <xsl:apply-templates/>
    </root>
    </xsl:template>
    <xsl:template match="MyClass">
        <MyClass>
            <Text>
               <xsl:attribute name="Value">
                    <xsl:value-of select="Text"/>
               </xsl:attribute>
            </Text>
        </MyClass>
    </xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)