【问题标题】:Deserialize elements to properties based on attribute根据属性将元素反序列化为属性
【发布时间】:2012-12-30 18:35:06
【问题描述】:

我正在寻找是否有一种简单的方法可以将填充了元素的 XML 文件反序列化回一类属性,特别是在元素属性“名称”上作为要附加到的属性。例如,我有一个 XML 文件格式:

<?xml version="1.0" encoding="utf-8"?>
<settings>
  <setting name="number_val_one">1</setting>
  <setting name="string_val_one">test</setting>
  <setting name="number_val_two">42</setting>
  <setting name="string_val_two">hello world</setting>
</settings>

我想知道是否有一种简单的方法可以将其反序列化回类似于这种格式的类:

public class SomeObject
{
    [XmlElement("number_value_one")]
    public Int32 NumberValueOne { get; set; }

    [XmlElement("number_value_two")]
    public Int32 NumberValueTwo { get; set; }

    [XmlElement("string_value_one")]
    public String StringValueOne { get; set; }

    [XmlElement("string_value_two")]
    public String StringValueTwo { get; set; }
}

我知道该格式不是序列化的最佳格式,但我无法更改此项目的文件格式。目前我正在手动阅读每个元素的值,这是很多代码并且相当混乱。要将其序列化回 xml,我使用反射来解决手动编写每个元素的需要。但我想知道是否有一种简单的方法来处理这种格式。

虽然不是所有元素都是字符串/整数,但有些是在读取等后要解析的自定义类型。

【问题讨论】:

    标签: c# xml serialization


    【解决方案1】:

    您可以使用 xslt 将输入字符串转换为 XmlSerializer 可识别的数据。

    var transform = new XslCompiledTransform();
    transform.Load(XmlReader.Create(new StringReader(transformText)));
    var memoryStream = new MemoryStream();
    transform.Transform(new XPathDocument(new StringReader(text)),null,memoryStream);
    memoryStream.Seek(0, SeekOrigin.Begin);
    var deserializer = new XmlSerializer(typeof(SomeObject)).Deserialize(memoryStream);
    

    在哪里

                var transformText = @"
    <xsl:stylesheet version=""1.0"" xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"">
        <xsl:output method=""xml"" encoding=""utf-8"" indent=""no""/>
        <xsl:template match=""/"">
            <SomeObject>
                <xsl:for-each select=""settings/setting"">
                    <xsl:element name=""{@name}"">
                        <xsl:value-of select="".""/>
                    </xsl:element>
                </xsl:for-each>
            </SomeObject>   
        </xsl:template>
    </xsl:stylesheet>";
    

            var text = @"
    <settings>
        <setting name=""number_val_one"">1</setting>
        <setting name=""string_val_one"">test</setting>
        <setting name=""number_val_two"">42</setting>
        <setting name=""string_val_two"">hello world</setting>
    </settings>";
    

    注意setting name 属性值必须与应用于属性的XmlElementAttribute 匹配。

    如果您不了解 xslt,请搜索它,那里有很多示例和 references

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-07-05
      • 2018-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-24
      相关资源
      最近更新 更多