2009-07-29 108 views
3

我接收XML響應如下:反序列化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")] 

我應該如何進行裝飾給定的屬性與一個新的命名空間相匹配?或者,我如何正確定義名稱空間?

我不是百分百使用股票數組作爲我的可枚舉部分,但我認爲命名空間問題目前需要謹慎。任何洞察力或想法非常感謝!

UPDATE:

我認爲現在的問題是更好的重新表述,我已經來回走了一點:

你如何使用XmlElementAttribute(或其他屬性)有一個類,它可以序列化到上面的項目片段,包括xsi標籤?

至於我的特殊問題,我已經意識到,由於Xml響應超出了我的控制範圍,所以我不需要xsi屬性開始。要解決此問題,系列化,我只是做了以下(XmlElement的元素包含原始文檔上方):

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

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

回答

0

不幸的是,這是有效的XML,並且完全符合XML標準。它驗證,它是正確的,它是完整的。

您遇到的問題是反序列化,它不是XML標準的一部分,與.NET將XML類型聲明爲內部CLR類型的映射有關。

xsi:type是一個名稱空間引用,旨在允許XML文檔將來自另一個名稱空間的派生類型替換爲該模式中聲明的類型。

我從我自己的經驗中知道,編碼人員往往會對這種事情甚至是合法的,更不正確的XML這種事情感到震驚。它基本上劫持你的模式。

您甚至不需要包含外部名稱空間以便將其視爲正確。

(請參閱本文更多的咆哮關於這個問題:http://norman.walsh.name/2004/01/29/trainwreck)現在

,至於如何處理所述問題:反序列化這個爛攤子。 1)處理XML文本並刪除xsi類型聲明,並希望沒有聲明擴展基類型的字段。 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,它將驗證但不正確反序列化。

1

你第一次是對的。 「java」不是一個命名空間。這是一個命名空間前綴。這是名稱空間的縮寫,用於XML。否則,無論您目前看到「java:」,實際名稱空間都需要重複。可以使用List<Item>而不是Item[]

+0

這對我來說很有意義,並沒有將「java」列爲名稱空間。但是,在傳入Xml響應的反序列化中,我收到「名稱空間前綴'java'未定義」的錯誤。 – 2009-07-29 15:50:23

相關問題