2011-01-25 66 views
4

我正在解析Python中的XML。我有一個XSD模式來驗證XML。我可以如何在XSD中定義XML的特定節點的類型嗎?是否有可能獲得它在XSD中定義的XML節點的類型?

例如,我的XML(小部分)是

<deviceDescription> 
    <wakeupNote> 
    <lang xml:lang="ru">Русский</lang> 
    <lang xml:lang="en">English</lang> 
    </wakeupNote> 
</deviceDescription> 

我的XSD是(再一次的一小部分):

<xsd:element name="deviceDescription" type="zwv:deviceDescription" minOccurs="0"/> 

<xsd:complexType name="deviceDescription"> 
    <xsd:sequence> 
    <xsd:element name="wakeupNote" type="zwv:description" minOccurs="0"> 
     <xsd:unique name="langDescrUnique"> 
     <xsd:selector xpath="zwv:lang"/> 
     <xsd:field xpath="@xml:lang"/> 
     </xsd:unique> 
    </xsd:element> 
    </xsd:sequence> 
</xsd:complexType> 

<xsd:complexType name="description"> 
    <xsd:sequence> 
    <xsd:element name="lang" maxOccurs="unbounded"> 
     <xsd:complexType> 
     <xsd:simpleContent> 
      <xsd:extension base="xsd:string"> 
      <xsd:attribute ref="xml:lang" use="required"/> 
      </xsd:extension> 
     </xsd:simpleContent> 
     </xsd:complexType> 
    </xsd:element> 
    </xsd:sequence> 
</xsd:complexType> 

在解析我想知道我的標籤wakeup注在XSD中定義爲complexType zwv:說明。如何做到這一點(在Python中)?

我需要什麼?假設我有很多這些XML,並且我想檢查它們是否都有填充英文的字段。很容易檢查<lang xml:lang="en"></lang>是否爲空,但是根本不允許指定該標籤。

這樣的想法是讓可能有語言描述的所有標記,並檢查<lang>標籤存在並具有EN一個非空的內容。

UPD

由於驗證期間我的XML是對XSD檢查,確認引擎知道類型的所有節點。 7個月前我有類似的問題,但仍然沒有答案。他們是相關的,恕我直言。 Validating and filling default values in XML based on XSD in Python

回答

0

如果問題是:如何找到給定XML節點的類型名稱? 答案是使用xpath in python來查找它。對XSD運行中的XPath將

//element[@name='wakeupNote']/@type 

,應返回zwv:描述。如果它返回兩種類型,你必須從根部走路

/root/foo/wakeupNote (type A) 
/root/bar/wakeupNote (type B) 

這將是單調乏味的從根部走下來。你將不得不尋找自主和命名類型。

如果問題是:如何查找給定類型的所有XML節點? 如果架構會頻繁更改,您可以在使用上述方法解析它時測試每個節點的類型。

如果架構衆所周知,修復,並且您正在尋找的節點可以用XPATH找到,那麼您可以測試每個節點。

//@xml:lang='en' 

然後用python檢查每個的長度。

在stable-schema的情況下,您可以編寫第二個XSD來執行您正在查找的條件。

+0

我想找到XSD定義爲'zwv所有XML節點:在XSD description`,而不是所有的定義。舉例來說,在我的XSD我可以定義兩個`wakeupNote`:一個`內deviceDescription`爲`zwv:description`和彼此標籤爲'zwv內:shortdescription`。所以在我的XML中,我會有兩種`wakeupNote`。我只需要選擇那些類型爲「zwv:description」的人。怎麼做? – PoltoS 2011-02-03 08:58:01

0

你是對的,驗證者必須知道它驗證的所有元素和屬性的類型關聯,並且驗證者因此能夠提供對該信息的訪問。

但是,無論是好還是壞,調用者和驗證程序之間的API以及調用程序可用的驗證相關信息的選擇均完全由實現定義。一些驗證器(Xerces J是一個值得注意的例子)提供了非常全面的驗證信息;別人不會。

不知道您使用的是什麼驗證程序,沒有人可以肯定地告訴您所查找的類型信息是否可用。由於您正在調用驗證器,因此必須有API;如果通過API可以獲得類型關聯,那麼大概文檔會這樣說。如果API不提供對它的訪問,這可能是因爲基礎架構驗證程序不提供訪問信息,也可能是因爲API的創造者並沒有看到這一點;你的工作(如果你想進一步追求的話)將是找出哪些是這種情況,然後試圖說服有關方面提供信息是有用的。

如果您沒有通過API訪問信息的運氣,您可以使用David W.的另一個答案中提到的更復雜版本的方法來幫助您自己。它是XSD模式的一個屬性,它的管理類型任何元素的嚴格的路徑,從驗證根該元素的功能,所以在原則上是簡單(如果超過一點在實踐中繁瑣的)來識別,任何元素的文檔實例,有什麼執政的類型將如果文檔實例針對特定模式進行了驗證。例如,對於您提到的情況,可以很簡單地告訴給定的wakeupNote是否具有deviceDescriptionotherElement作爲祖先,或者如果wakeupNote具有兩者,哪個是更近的祖先,並且基於該知識推斷適當的控制類型定義。

以這種方式幫助自己很可能需要一些不重要的工作。如果有通用工具來計算這些信息並以各種形式訪問,這將有所幫助,但如果有這樣的信息,我不知道它們。 (我知道那些可以收費的人可以構建這樣的工具。)因此,如果我是你,我會嘗試首先通過API獲取信息。

相關問題