2012-10-28 67 views
3

我試圖使用XML Schema Definition Tool來從下面的模式CS代碼序列化派生類型:.NET的XmlSerializer(DE)從不同的命名空間的架構編譯XSD.EXE和錯誤的命名空間與

A.xsd

<?xml version="1.0" encoding="UTF-8"?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"> 
    <xs:complexType name="Bar"> 
     <xs:sequence> 
      <xs:element name="v" type="xs:double"/> 
     </xs:sequence> 
    </xs:complexType> 
    <xs:complexType name="Base"/> 
    <xs:element name="root" type="Base" /> 
</xs:schema> 

B.xsd

<?xml version="1.0" encoding="UTF-8"?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ns1="v2" targetNamespace="v2" elementFormDefault="qualified"> 
    <xs:import schemaLocation="A.xsd"/> 
    <xs:complexType name="Derived"> 
     <xs:complexContent> 
      <xs:extension base="Base"> 
       <xs:sequence> 
        <xs:element name="b" type="Bar"/> 
       </xs:sequence> 
      </xs:extension> 
     </xs:complexContent> 
    </xs:complexType> 
</xs:schema> 

我執行XSD.EXE模式編譯器是這樣的:

xsd.exe A.xsd B.xsd/c

並得到一個B_A.cs文件(很多代碼,隨時重新生成自己)。

有兩種行爲意想不到的部分。

連載: 如果序列派生類型的酒吧的一個實例:

XmlSerializer serializer = new XmlSerializer(typeof(Base)); 
    Derived d = new Derived(); 
    d.b = new Bar(); 
    d.b.v = 12.123; 
    serializer.Serialize(Console.Out, d); 

你得到這樣的:

<?xml version="1.0" encoding="ibm850"?> 
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:q1="v2" xsi:type="q1:Derived"> 
    <q1:b> 
    <q1:v>12.123</q1:v> 
    </q1:b> 
</root> 

不與B.xsd驗證beceause的Ⅴ族元素在b中是以q1爲前綴的名稱空間。擺脫前綴,它驗證,因爲(我相信)是正確的。

同樣地,周圍的其他方法。拿這個實例文檔,驗證:

<?xml version="1.0" encoding="utf-8"?> 
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:q1="v2" xsi:schemaLocation="v2 B.xsd" xsi:type="q1:Derived"> 
    <q1:b> 
    <v>12.123</v> 
    </q1:b> 
</root> 

嘗試生成的代碼以反序列化,像這樣:

XmlSerializer serializer = new XmlSerializer(typeof(Base)); 
    Bar p = (Bar)serializer.Deserialize(new FileStream(@"..\..\test.xml", FileMode.Open)); 
    Console.Out.WriteLine(p.v); 

你得到0.0輸出,becaues v是默認初始化。將q1:前綴添加到實例文檔的v元素中,它可以工作,但無效。

有人會同意,這是XML Schema定義工具的錯嗎?我不相信它會生成正確的序列化代碼,但很難責怪這些工具。如果我們將Namespace =「」的XmlElement屬性添加到v中,它就可以工作,但現在我正在修改生成的代碼,這是不可取的(我正在工作的項目生成代碼作爲構建的一部分 - 我們不是應該改變它)。

任何想法我怎麼能解決此問題?

+0

隨口說說,我希望XSD有這個問題,因爲模式是不是在一個命名空間。我建議從你想要的代碼開始,然後從中產生一個模式,假設你需要一個模式。 –

+0

我已經做了很多序列化,我總是發現XML模式的東西太複雜了。你有這樣做的具體要求嗎,還是你願意接受其他方法? – theMayer

+0

c#代碼的生成只是一個方面 - 我們對於ANSI C++應用程序也是這樣做的,並使用Codesynthesis XSD(偉大的工具,沒有這個問題)生成它的序列化例程。我想切換到比XML(Goggle協議緩衝區,甚至JSON)更好的東西,但我們現在使用的是XML,這個小小的Hickup並不值得改變一切。 – paquetp

回答

0

嗯,我有件事情我想我可以用 - 我加入了一個XmlRootAttribute(命名空間=「」)的酒吧部分類一個單獨的CS模塊中。