使用未定义的名称空间前缀反序列化xml

时间:2009-07-29 15:36:00

标签: c# xml-serialization

我收到的Xml回复如下:

<response>
    <item xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="java:com.someDomain.item">
        <name>some name</disc-name>
        <description>some description</disc-desc>
    </item>
    <item xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="java:com.someDomain.item">
            <name>some name</disc-name>
            <description>some description</disc-desc>
    </item>
    <otherValue>12.1</otherValue>
</response>

我的班级装饰如下:

[XmlElement("item")]
public Item[] Items{get;set;}
[XmlElement("otherValue")
public string OtherValue{get;set;}

当我尝试将上述Xml反序列化为所描述的类时,我收到错误“名称空间前缀'java'未定义”。将“namespace”属性添加到类可以解决解析错误(但是,xml会从原始位置失真)。

[XmlElement(ElementName="item",Namespace="java")]

我应该如何装饰给定的属性以匹配新的命名空间?或者,我如何正确定义命名空间?

我也不是100%使用库存数组作为我的可枚举部分,但我认为命名空间问题目前是预先确定的。任何见解或想法都非常感谢!

更新:

我认为现在问题更好了,我已经来回走了一段时间:

如何使用XmlElementAttribute(或其他属性)来创建可以序列化到上面的项目片段的类,包括xsi标记?

至于我的特殊问题,我已经意识到,由于Xml响应不受我的控制,我不需要开始使用xsi属性。要解决序列化问题,我只是执行以下操作(XmlElement元素包含上面的原始文档):

foreach(XmlNode node in element)
node.Attributes.RemoveAll();

我只注意到我的个人解决方法,因为这实际上不是解决方案。

2 个答案:

答案 0 :(得分:1)

你第一次是对的。 “java”不是命名空间。它是名称空间前缀。这是名称空间的缩写,用于XML。否则,无论您当前看到“java:”。

,都需要重复实际的命名空间

您可以使用List<Item>代替Item[]

答案 1 :(得分:0)

不幸的是,这是有效的XML,并且完全符合XML标准。 它验证,它是正确的,它是完整的。

您遇到的问题是反序列化,它不是XML标准的一部分,与.NET如何将XML类型声明为内部CLR类型有关。

xsi:type是一个名称空间引用,旨在允许XML文档将另一个名称空间中的派生类型替换为模式中声明的类型。

根据我自己的经验,我知道编码人员往往会感到震惊,这种事情甚至是合法的,更不正确的XML。它基本上劫持了你的架构。

您甚至不需要包含外部命名空间,以使其被认为是正确的。

(有关此主题的更多咆哮,请参阅此文章:http://norman.walsh.name/2004/01/29/trainwreck

现在,关于如何处理你陈述的问题:反序列化这个烂摊子。 1)处理xml文本并删除xsi-types声明,并希望没有声明扩展基类型的字段。 2)声明一种从模式中的基类型派生的类型。

如下所示:

// note this "XmlIncludeAttribute" references the derived type.
// note that in .NET they are in the same namespace, but in XML they are in different namespaces.
[System.Xml.Serialization.XmlIncludeAttribute(typeof(DerivedType))]
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://BaseNameSpace")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="http://BaseNameSpace", IsNullable=true)]
public partial class MyBaseType : object
{
...
}

/// <remarks/>
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://DerivedNameSpace")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="http://DerivedNameSpace", IsNullable=true)]
public partial class DerivedType: MyBaseType 
{
...
}

这只是一个粗略的轮廓,希望足以让你开始。请注意,这不是一个容易解决的问题,因为总是有人能够为您提供XML并且它将验证但不能正确地反序列化。