【问题标题】:XML Deserialisation and XPath?XML 反序列化和 XPath?
【发布时间】:2013-01-02 14:10:49
【问题描述】:

我有这样的 Xml

            <pda:Party>
                 ...Snip....
                <pda:CitizenName>
                    <pda:CitizenNameTitle>MR</pda:CitizenNameTitle>
                    <pda:CitizenNameForename>John</pda:CitizenNameForename>
                    <pda:CitizenNameSurname>Wayne</pda:CitizenNameSurname>
                </pda:CitizenName>
              .....Snip...
           </pda:Party>

其中 Citizen Name 是派对节点中的复杂类型。 (这是从我正在为其创建适配器的第 3 方集成收到的 xml)

我对在我的班级中有一个子类型不感兴趣,我试图反序列化为我宁愿拥有的。

public class Party
{
    public string  FirstName { get; set; }
    public string LastName {get;set;}

}

因此,与其将我的类定义作为 XML 所代表的具体定义,我可以用 XPath 之类的东西来装饰属性,例如。

 [XmlElement("\CitizenName\CitizenNameForeName")]
 public string FirstName {get;set;}

要从 xml 中挑选信息到包含我感兴趣的数据的类中?

从第 3 方收到的 xml 非常冗长,我只对特定方面感兴趣。一种选择是创建一个 XMLDocument 并使用 XPath 和转换方法手动映射到我的类,但我想我会问是否有中间解决方案?

【问题讨论】:

    标签: c# xml serialization


    【解决方案1】:

    一种选择是使用 XSLT 转换将传入的 XML 解析为与您的类匹配的 s 格式。

    【讨论】:

    • 我在 XSLT 方面并不出色,我之前曾涉足过,但是由于 XML 的数量被撤回,我不相信这将是一种可行的方式有。不过谢谢你的建议。
    【解决方案2】:

    最后,我设置了自己的属性来做我想做的事情。因此,采用 XPath 路径的自定义属性...

    [System.AttributeUsage(System.AttributeTargets.Property)]
    public class PathToXmlNode : System.Attribute
    {
        public string Path { get; set; }
    
        public PathToXmlNode(string path)
        {
            this.Path = path;
        }
    }
    

    后跟一个装饰属性..(为简单起见省略了命名空间)

             [PathToXmlNode("Party[1]/CitizenName/CitizenNameForename")]
             public string FirstName { get; set; }
    

    然后,当我想填充类时,我调用了以下方法。

            var type = typeof(T);
            foreach (var property in type.GetProperties())
            {
                var attributes = property.GetCustomAttributes(typeof(PathToXmlNode), true);
    
                if (attributes != null && attributes.Length > 0)
                {
                    //this property has this attribute assigned.
                    //get the value to assign
                    var xmlAttribute = (PathToXmlNode)attributes[0];
                    var node = doc.SelectSingleNode(xmlAttribute.Path, nmgr);
    
    
                    if (node != null && !string.IsNullOrWhiteSpace(node.InnerText))
                    {
                        dynamic castedValue;
    
                        if (property.PropertyType == typeof(bool))
                        {
                            castedValue = Convert.ToBoolean(node.InnerText);
                        }
                        ...Snip all the casts....
                        else
                        {
                            castedValue = node.InnerText;
                        }
    
    
                        //we now have the node and it's value, now set it to the property.
                        property.SetValue(obj, castedValue, System.Reflection.BindingFlags.SetProperty, null, null, System.Globalization.CultureInfo.CurrentCulture);
                    }
    
                }
            }
    

    这是一个很好的起点,但是如果其他人认为这是一个可行的中间解决方案,您需要注意它需要适应非简单数据类型。这就是我现在要做的!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-02
      • 1970-01-01
      • 1970-01-01
      • 2014-10-04
      • 2013-09-24
      • 2012-03-04
      • 2011-03-03
      相关资源
      最近更新 更多