簡體   English   中英

使用未定義的名稱空間前綴反序列化xml

[英]Deserializing xml with namespace prefixes that are undefined

我收到的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();

我只是注意到我的個人解決方法,因為這實際上不是解決方案。

你是第一次是對的。 “java”不是命名空間。 它是名稱空間前綴。 這是名稱空間的縮寫,用於XML。 否則,無論您當前看到“java:”,都需要重復實際的命名空間。

您可以使用List<Item>而不是Item[]

不幸的是,這是有效的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並且它將驗證但不能正確地反序列化。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM