使用反序列化XmlSerializer.Deserialize()在C#中的父母的名字空间之外的子节点 [英] Deserializing child nodes outside of parent's namespace using XmlSerializer.Deserialize() in C#

查看:1075
本文介绍了使用反序列化XmlSerializer.Deserialize()在C#中的父母的名字空间之外的子节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用的命名空间,以帮助存储在XML反序列化对象的应用程序。 XML命名空间也是对象所在的C#命名空间。例如,假设下面的XML剪断:

I have an application that uses namespaces to help deserialize objects stored in XML. The XML namespace is also the C# namespace where the object resides. For example, given the following XML snip:

<xml-config xmlns:app="MyAppNS">
  <app:Person>
    <Name>Bill</Name>
    <Car>
      <Make>Honda</Make>
      <Model>Accord</Model>
    </Car>
  </app:Person>

  <app:Person>
    <Name>Jane</Name>
    <Car>
      <Make>VW</Make>
      <Model>Jetta</Model>
    </Car>
  </app:Person>

  <app:Car>
    <Make>Audi</Make>
    <Model>A6</Model>
  </app:Car>
</xml-config>



配置确实是对象的只是一个随机的袋子。正如你所看到的,有混合对象在顶层。我用命名空间来确定在加载时进行适当的反序列化对象类型。下面是加载文档中的代码:

The configuration is really just a random bag of objects. As you can see, there is a mix of Person and Car objects at the top level. I use the namespace to determine the object type at load time for proper deserialization. Here is the code for loading the document:

public static void LoadFile(String file) {
    XmlDocument doc = new XmlDocument();
    doc.Load(file);

    XmlNode root = doc.DocumentElement;
    foreach (XmlNode child in root.ChildNodes) {
        if (child.NodeType != XmlNodeType.Element) {
            continue;
        }

        Object obj = LoadObject(child);
        // TODO handle object here...
    }
}

private static Object LoadObject(XmlNode node) {
    Object obj = null;

    StringBuilder str = new StringBuilder();
    if ((node.Prefix != null) && (node.Prefix != "")) {
        str.Append(node.NamespaceURI).Append('.');
    }
    str.Append(node.LocalName);

    Assembly assy = Assembly.GetExecutingAssembly();
    Type type = assy.GetType(str.ToString());
    XmlSerializer serdes = new XmlSerializer(type);

    using (XmlNodeReader reader = new XmlNodeReader(node)) {
        obj = serdes.Deserialize(reader);
    }

    return obj;
}

您多看这个问题的时候了,但是当使用该代码,结果对象是空的,但是没有错误。获得解串器来填充子元素的唯一方法是使用相同的命名空间的子元素:

You many see the issue right away, but when this code is used, the resulting Person objects are empty, however there are no errors. The only way to get the deserializer to populate the child elements is to use the same namespace for the child elements:

  <app:Person>
    <app:Name>Bill</app:Name>
    <app:Car>
      <app:Make>Honda</app:Make>
      <app:Model>Accord</app:Model>
    </app:Car>
  </app:Person>



我已经试过唯一的其他选择是使用完全限定的类型名称作为元素名(无命名空间),但是我还没有与任何运气。有没有一种方法,使解串器接受XML节点的不带前缀的孩子?

The only other option I have tried is to use fully-qualified type names as the element name (no namespaces), however I haven't had any luck with that. Is there a way to cause the deserializer to accept the non-prefixed children of the XML node?

推荐答案

我终于找到了一个方法要做到这一点,修改答案发现 href=\"http://stackoverflow.com/questions/870293/can-i-make-xmlserializer-ignore-the-namespace-on-deserialization\">。

I finally found a method to accomplish this, modifying the answer found here.

我创建了一个复制的起始节点的名称空间的自定义解串器:

I created a custom deserializer that replicates the namespace for the starting node:

public class CustomXmlNodeReader : XmlNodeReader {

    private String _namespace;

    public CustomXmlNodeReader(XmlNode node) : base(node) {
        _namespace = node.NamespaceURI;
    }

    public override String NamespaceURI {
        get { return _namespace; }
    }
}



使用这个阅读器,我能够加载存储使用(XmlNodeReader对象读卡器=新CustomXmlNodeReader(节点))

Using this reader, I am able to load stored objects with the following:

using (XmlNodeReader reader = new CustomXmlNodeReader(node)) {
    obj = serdes.Deserialize(reader);
}



我知道这是一个有点坏的形式为XML(强制的应用特定的命名空间),但它适合我的需要很好地。在这里得到解答的情况下,它可以帮助其他人。

I know this is a bit bad form for XML (forcing the application of a specific namespace), however it suits my needs quite nicely. Answered here in case it helps anyone else.

这篇关于使用反序列化XmlSerializer.Deserialize()在C#中的父母的名字空间之外的子节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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