2010-07-01 74 views
2

我正在編寫一個XSLT,用於將XML文件轉換爲可讀的HTML頁面。如何使用XSD中的註釋將XML整數映射到相關描述?

的XML有幾個字段來描述數據,其中包含代表映射字符串整數的某些方面。整數不是用戶想要的信息,我需要將這些整數映射到相應的字符串。

映射的字符串是在XSD註釋可用。

例如:

<typewoning>1</typewoning> 

繼XSD聲明:

<xs:element name="typewoning" type="TypeWoningEnum"/> 

映射到:

<xs:simpleType name="TypeWoningEnum"> 
    <xs:restriction base="xs:integer"> 
     <xs:enumeration value="1"> 
      <xs:annotation> 
       <xs:documentation>vrijstaande woning</xs:documentation> 
      </xs:annotation> 
     </xs:enumeration> 
     <xs:enumeration value="2"> 
      <xs:annotation> 
       <xs:documentation>twee-onder-een-kap/rijwoning hoek</xs:documentation> 
      </xs:annotation> 
     </xs:enumeration> 

等等等等

因此,在這種情況下,我想顯示註釋n代表價值1,應該是'vrijstaan​​de woning'。

什麼是處理這個的最好方法?我並不是那種在XML/XSLT中有經驗的人知道任何這些解決方案,而且我的谷歌搜索已經變得毫無用處。

在此先感謝。

+0

看來你在這裏有交叉引用。這可以通用的方式完成,不會「污染」你的樣式表。它需要使用'xsl:key'。如果您提供了一個簡化但完整的兩個輸入文檔(數據和模式)和所需輸出的示例,則有人可以發佈答案 – 2010-07-01 16:35:45

回答

3

如果我讀這正確的,那麼你正在試圖做的是不是直線前進。 XML文檔和模式之間沒有「魔術」連接,您必須在樣式表中加載架構並在其中找到文檔。

假設在某一點XSLT樣式表是在一個位置,typewoning是上下文元素(即value-of select="typewoning"將輸出其價值),你可以這樣做:

<xsl:variable name="schema" select="document('my-schema.xsd')/xsd:schema"/> 

<xsl:variable name="type" select="$schema//xsd:simpleType[@name = 'TypeWoningEnum']"/> 

<xsl:variable name="value" select="$type//xsd:enumeration[@value = typewoning]//xsd:documentation"/> 

<xsl:value-of select="$value"/> 

一些解釋:

  1. 第一步使用XSL文檔函數將模式加載到一個變量中
  2. 第二步找到正確的類型(您可能會更喜歡並找到使用類型該元素在文檔中的類型,但後來模式驗證將不得不對,你需要一個兼容模式,XSLT引擎)
  3. 第三步找到的文檔的價值輸出,給您typewoning元素的內容。

第四步將結果寫出來,因爲你要使用。

編輯:另一種方法是,如果您願意使用符合架構的XSLT引擎,例如saxon的付費版本。假設所有的枚舉從integer派生,你可以將某些父節點的範圍內嘗試這個辦法:

<xsl:variable name="schema" select="document('my-schema.xsd')/xsd:schema"/> 

<xsl:for-each select="element(*, xsd:integer)"> 
    <xsl:variable name="type" select="$schema//xsd:simpleType[@name = local-name(current())]"/> 

    <xsl:if test="$type"> 
     <xsl:variable name="value" select="$type//xsd:enumeration[@value = current()/text()]//xsd:documentation"/> 

     <xsl:text>Value: </xsl:text> <xsl:value-of select="$value"/> 
    </xsl:if> 
</xsl:for-each> 
+0

謝謝您的詳細闡述。我希望可能有一些魔術映射工具,它將整數映射爲XSD中的註釋的枚舉類型的一部分。 我有大約20到30個字段,我必須執行這個映射,所以你的解決方案,雖然很好和正確,但會污染我的'to-HTML'xsl樣式表。 我想我可能會使用你的代碼先執行xml源代碼的映射,然後輸出'mapped'xml源代碼,然後我會將其轉換爲html。 我甚至正在考慮編寫一個XSL來將XSD轉換爲一個將執行映射的XSL ......瘋狂。 – 2010-07-01 14:43:53

+0

@Symen Timmermans:看來你在這裏有交叉引用。這可以通用的方式完成,不會「污染」你的樣式表。它需要使用'xsl:key'。如果您提供了一個簡化但完整的兩個輸入文檔(數據和模式)和所需輸出的示例,則有人可以發佈答案。 – 2010-07-01 16:35:03

+0

@Symon Timmermans:添加了一個進一步的例子,說明如果您願意使用支持模式的XSLT處理器,這可以如何簡化。 – xcut 2010-07-02 08:11:26

2

我已經把一些時間和精力投入到這一點,我決定寫一個XSLT的模式轉變爲映射基於每個xs:simpleType中找到的枚舉文檔。

此代碼:

<xsl:stylesheet 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:xs="http://www.w3.org/2001/XMLSchema" 
version="1.0"> 

<xsl:output method="xml" version="1.0" 
    encoding="utf-8" indent="yes"/> 

<xsl:strip-space elements="*"/> 

<xsl:template match="xs:schema"> 
    <mappings> 
     <xsl:for-each select="//xs:element[contains(@type, 'Enum')] | //xs:element[contains(@type, 'JaNee')]"> 
      <xsl:variable name="type" select="@type" /> 
      <xsl:element name="{concat(@name, 'Mapping')}" > 
       <xsl:apply-templates select="//xs:simpleType[@name=$type]"> 
        <xsl:with-param name="elemname" select="@name" /> 
       </xsl:apply-templates> 
      </xsl:element> 
     </xsl:for-each> 
    </mappings> 
</xsl:template> 

<xsl:template match="xs:enumeration"> 
    <xsl:param name="elemname" select="'undefined'" /> 
    <xsl:element name="{$elemname}"> 
     <xsl:attribute name="value"> 
      <xsl:value-of select="@value" /> 
     </xsl:attribute> 
     <xsl:value-of select="xs:annotation/xs:documentation" /> 
    </xsl:element> 
</xsl:template> 

輸出正是我所期待的:

...snip... 
    <typewoningMapping> 
     <typewoning value="1">vrijstaande woning</typewoning> 
     <typewoning value="2">twee-onder-een-kap/rijwoning hoek</typewoning> 
     <typewoning value="3">rijwoning tussen</typewoning> 
     <typewoning value="4">galerijflat (hoogbouw)</typewoning> 
     <typewoning value="5">portiekflat (etage)</typewoning> 
     <typewoning value="6">maisonnettewoning</typewoning> 
     <typewoning value="7">flatwoning (overig)</typewoning> 
     <typewoning value="8">woongebouw met niet-zelfstandige woonruimte</typewoning> 
    </typewoningMapping> 
    ...snip... 

現在我只寫一些東西,讓使用xsl一個xsl:關鍵標籤爲我想要使用的映射定義。

感謝大家一路幫助我。

相關問題