即使根节点与其子节点在不同的名称空间中,我也可以避免用重复的XmlElement属性使类混乱吗?

本文关键字:可以避免 属性 混乱 XmlElement 子节点 根节点 空间 | 更新日期: 2023-09-27 18:11:26

我正在从一个我无法控制的web服务检索XML文档。XML的格式类似如下:

<?xml version="1.0"?>
<ns:obj xmlns:ns="somenamespace">
     <address>1313 Mockingbird Lane</address>
     <residents>5</residents>
</ns:obj>

,其中根节点在"ns"命名空间中,但它的所有子元素都不在。

经过一些尝试和错误之后,我发现我可以通过执行以下操作将文档反序列化为c#对象:

[XmlRoot(Namespace="somenamespace", ElementName="obj")]
public class xmlObject
{
    [XmlElement(Namespace = "")]
    public string address { get; set; }
    [XmlElement(Namespace = "")]
    public int residents { get; set; }
}
class Program
{
    static void Main(string[] args)
    {
        string xml =
            "<?xml version='"1.0'"?>" +
            "<ns:obj xmlns:ns='"somenamespace'">" +
            "   <address>1313 Mockingbird Lane</address>" +
            "   <residents>5</residents>" +
            "</ns:obj>";
        var serializer = new XmlSerializer(typeof(xmlObject));
        using (var reader = new StringReader(xml))
        {
             var result = serializer.Deserialize(reader) as xmlObject;
             Console.WriteLine("{0} people live at {1}", result.residents, result.address);
             // Output: "5 people live at 1313 Mockingbird lane"
        }
    }
}

如果省略单个成员的XmlElementAttribute,则得到一个空对象。即输出为

0 people live at 

(result.address = null)

我理解为什么反序列化过程像这样工作的基本原理,但是我想知道是否有一种不那么冗长的方法来告诉XmlSerializer对象的子元素不在与根节点相同的命名空间中。

我在生产中使用的对象有几十个成员,为了干净起见,如果可以避免的话,我想避免用[XmlElement(Namespace = "")]标记它们。

即使根节点与其子节点在不同的名称空间中,我也可以避免用重复的XmlElement属性使类混乱吗?

您可以将XmlRootAttributeXmlTypeAttribute结合使用,从而使根元素和根元素的元素具有不同的命名空间:

[XmlRoot(Namespace="somenamespace", ElementName="obj")]
[XmlType(Namespace="")]
public class xmlObject
{
    public string address { get; set; }
    public int residents { get; set; }
}

使用上面的类型,如果我反序列化和重新序列化您的XML,我得到:

<q1:obj xmlns:q1="somenamespace">
  <address>1313 Mockingbird Lane</address>
  <residents>5</residents>
</q1:obj>

样本小提琴。

如果您知道与web服务的契约,为什么不使用DataContractSerializer将XML反序列化为对象呢?