2011-05-04 64 views
0

我使用内置的XML反序列化(不是因为它是我的选择,而是遗留代码)将xml反序列化为强类型对象。使用C#中的内置xml反序列化从外部API反序列化xml时的重复值

注:我有过XML无法控制,它是一个外部API

的问题是一个XML节点已经扩展到包括同名的子节点,它打破了系列化。

例如,XML如下:

<people> 
    <person> 
    <id>1234</id> 
    <person> 
     <name>This is my name</name> 
    <person> 
    </person> 
</people> 

随着下列对象

[XmlType("person")] 
public class Person { 

    [XmlElement("id")] 
    public int Id { get; set; } 

    [XmlElement("person")] 
    public PersonTitle Title{ get; set; } 
} 

[XmlType("person")] 
pulic class PersonTitle 
{ 
    [XmlElement("name")] 
    public string Name { get; set; } 
} 

这被调用(T)xmlserializer.Deserialize(流)时引发错误由于即使xml有效,重复的名称也是如此。就我个人而言,当手动反序列化更容易维护时(特别是当它永远不会被序列化为.net时),我不会在复制对象中的xml布局时自动反序列化它。

但是,我想知道是否有办法解决这个问题,即使这意味着将子对象展开。

我知道这是不行的,但作为例子:

[XmlType("person")] 
public class Person { 

    [XmlElement("id")] 
    public int Id { get; set; } 

    [XmlElement("person/name")] 
    public string Title{ get; set; } 
} 

任何帮助表示赞赏。

回答

2

最简单的方法可能是在反序列化之前通过XSLT转换运行它 - 匹配person/person/name元素并仅输出person/name部分。然后反序列化结果。

这里有一个SO张贴在C#中应用XSLT:How to apply an XSLT Stylesheet in C#

这里是一个使用XSLT来代替元素:http://cvalcarcel.wordpress.com/2008/09/06/replacing-arbitrary-xml-located-within-an-xml-document-using-xslt/

+0

好的,所以真的没有办法绕过反序列化器坚持要将子元素唯一地命名为父元素吗? – Gats 2011-05-04 03:43:05

+1

不是以我的经验,但我已被证明错误! – 2011-05-04 03:49:07

+1

虽然我怀疑它是可能的,但可以将名称属性和适当归因的NestedPerson属性添加到person类,并使所有属性在语义上可选。这可能会诱使XmlSerializer创建一个具有所有其他属性的外部人员实例,而另一个人员实例则只使用名称属性集合的NestedPerson属性。但是这看起来更像是一种黑客而不是XSLT预处理器。 – 2011-05-04 03:53:09

0

在最糟糕的情况下,您可以编写类,但不管您喜欢(不要因为序列化而妥协),然后实现IXmlSerializable。如果你喜欢,实现ReadXml,为WriteXml抛出NotImplementedException。

+0

它被写入到匹配的XML发送给我们。问题是XmlSerializer不喜欢父元素和子元素共享“person”的XmlElement。只是想知道是否有解决办法比重写那里的解析更快。这是一个非常复杂的休息界面,需要几天的时间来重写。 – Gats 2011-05-04 03:25:30