2011-10-24 141 views
3

我的項目的一部分涉及到用戶定義的模式文檔的大量轉換。我需要能夠更改目標名稱空間,支持類型交叉引用並在多個模式文檔上構建wsdl。 最常用的操作之一是在將模式導入wsdl文件之前更改命名空間前綴。我正在使用org.xml.sax.ContentHandler和它的startPrefixMapping方法來處理名稱空間。除非我想改變元素類型,否則所有的工作都很好,並且完美無瑕。XML架構。處理名稱空間感知屬性值

這裏是簡單的模式片段

<schema xmlns="http://www.w3.org/2001/XMLSchema"> 
    <complexType name="Param"> 
    <sequence> 
     <element name="key" type="string"/> 
     <element name="value" type="string"/> 
    </sequence> 
    </complexType> 
<!-- omitted --> 

必須被置於其內的wsdl如下:

<definitions xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <types> 
    <xs:schema> 
     <xs:complexType name="Param"> 
     <xs:sequence> 
      <xs:element name="key" type="xs:string"/> <!-- 'xs:' to be added --> 
      <xs:element name="value" type="xs:string"/> <!-- 'xs:' to be added --> 
     </xs:sequence> 
     </xs:complexType> 
<!-- omitted --> 

的問題是,一些模式的屬性值(type<element>base<extension>)是名稱空間感知,並可能在上面的示例中更改。正如我所看到的,DOM和SAX解析器都無法處理這種情況,因此我正在使用醜陋的字符串操作從特定屬性值檢索名稱空間信息。

我錯過了什麼?是否有任何API,庫或其他特定於架構的工具來處理此類任務?

+0

這是一種煩人的...前綴不是元素或屬性的限定名稱的一部分,但它是字符數據的一部分。解析器不會內在地意識到這一點。我曾經問過一個問題,[讓我想起你的問題](http://stackoverflow.com/questions/5634416/jaxb-bindings-file-namespace-aware-node-selection)。也許你可以通過一個XSLT樣式表傳遞XML,該樣式表處理屬於架構名稱空間的元素中遇到的某些屬性的內容(如'type')。 –

+0

@G_H,感謝您的評論。使用XSLT似乎是可以接受的解決方案,尤其是在閱讀了jtahlborn關於這個主題的看法之後。 – Osw

回答

3

是的,這是xml schema/wsdl中的一個主要錯誤。在屬性值中使用xml名稱空間前綴是一個巨大的錯誤(因爲前綴值本身並不重要,只有實際名稱空間的佔位符)。不幸的是,我不知道有什麼好的解決方案(我必須實現幾乎相同的想法:將多個用戶定義的模式合併到一個模式/ wsdl中)。我知道xerces有xml schema model api,但我不知道它是否支持將多個模式合併在一起並生成結果輸出。

1

SAX是用於讀取模式文檔的非常低的級別。如果您轉移到更高級別的界面(如XSLT),您將消除很多麻煩。如果您使用模式處理器將模式文檔轉換爲模式組件模型來讀取模式文檔,那麼您將刪除更多麻煩 - Xerces和Saxon都可以執行此操作,而且它們並不孤單。