XmlSerializer的:序列化类属性作为一个自定义子元素的属性 [英] XmlSerializer: serializing a class property as an attribute of a custom subelement

查看:205
本文介绍了XmlSerializer的:序列化类属性作为一个自定义子元素的属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是的XmlSerializer 。我的类:

  [Serializable接口] 
[XmlRoot(的ElementName =MyClass的)]
公共类MyClass的
{
公共字符串值;
}



我想序列化,使最终为一个命名(例如)文本子元素的属性。



期望的结果:

 < MyClass的> 
<文本值=3/>
< / MyClass的>



不会(这将是标记值作为效果 XmlAttribute

 < MyClass的值=3> 
< / MyClass的>



不可以(这将是标记值作为效果的XmlElement ):

 < MyClass的> 
< VALUE>第3版; /价值与GT;
< / MyClass的>



我如何做到这一点?



我知道我可以改变值类型从串到另一个序列化的自定义类。



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



有没有更快的解决方案?






编辑:



在回答您的意见:




  • 没有,不是每个酒店有被序列化到一个名为文本子元素。子元素的名称是唯一的和明确的。


  • 示例输出XML:

     <能见度和GT; 
    <现场可见=YES/>
    <比较可见=NO/>
    <过期天数=7/>
    <注释和GT; blahblahblah< /评论>
    <能见度和GT;


  • Sample类:




  [XmlRoot(的ElementName =能见度)] 
酒店的公共类可视性
{
[XPath的(/网站@可见)] //如果只有这是可能的!
公共字符串的OnSite
{
{返回SiteVisible? 是:无; }
}

[XPath的(/ @比较可见)] //如上...
公共字符串InComparator
{
获得{返回ComparatorVisible? 是:无; }
}

[XmlIgnore]
公共BOOL SiteVisible;
[XmlIgnore]
公共BOOL ComparatorVisible;

[XPath的(/到期日@)] //如上...
公众诠释ExpiresAfterDays;

[XmlElement的(评论)] //这是很容易
公共字符串评论;
}


解决方案

在不改变的类型我认为这是不可能的。您可以添加属性的XmlElement(的ElementName =文本)但你会获得类似这样的结果

 < MyClass的> 
<文本>第3版; /文本>
< / MyClass的>



编辑:
另一种解决方案可以包括XSLT转换:您。可使用的.Net序列生成xml并应用XML转换后

 的XslTransform myXslTransform =新的XslTransform(); 
myXslTransform.Load(xsltDoc);
myXslTransform.Transform(sourceDoc,resultDoc);



我的榜样的改造中应该是这样的:

 <的xsl:样式版本=1.0的xmlns:XSL =http://www.w3.org/1999/XSL/Transform> 
<的xsl:模板匹配=/>
<根和GT;
< XSL:申请模板/>
< /根>
< / XSL:模板>
<的xsl:模板匹配=MyClass的>
< MyClass的>
<文本>
<的xsl:属性名称=值>
< XSL:选择=TEXT/>值的;
< / XSL:属性>
< /文本>
< / MyClass的>
< / XSL:模板>
< / XSL:样式>


I'm using an XmlSerializer. My class:

[Serializable]
[XmlRoot(ElementName="MyClass")]
public class MyClass
{
    public string Value;
}

I would like to serialize it so that Value ends up as an attribute of a subelement named (for instance) "Text".

Desired outcome:

<MyClass>
    <Text Value="3"/>
</MyClass>

But NOT (which would be the effect of marking Value as an XmlAttribute)

<MyClass Value="3">
</MyClass>

And NOT (which would be the effect of marking Value as an XmlElement):

<MyClass>
    <Value>3</Value>
</MyClass>

How do I achieve this?

I am aware that I could change the type of Value from string to another serializable custom class.

Unfortunately, I have plenty of such properties, so I'd need to create dozens of tiny classes.

Is there any quicker solution?


EDIT:

In response to your comments:

  • No, not every property has to be serialized to a subelement named "Text". Subelement's name is unique and unambiguous.

  • Sample output XML:

    <visibility>
        <site visible="yes"/>
        <comparator visible="no"/>
        <expiration days="7"/>
        <comment>blahblahblah</comment>
    <visibility>
    

  • Sample class:

!

[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;
}

解决方案

Without changing the type of Value I think it's not possible. You can add the attribute XmlElement(ElementName="Text") on Value but you will obtain a result similar to this:

<MyClass> 
    <Text>3</Text> 
</MyClass> 

Edited: Another solution can involve XSLT transformation: you can generate the xml using .Net serialization and after apply a xml transformation.

XslTransform myXslTransform = new XslTransform();
myXslTransform.Load(xsltDoc);
myXslTransform.Transform(sourceDoc, resultDoc);

The trasformation of my example should be something like this:

<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>

这篇关于XmlSerializer的:序列化类属性作为一个自定义子元素的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆