2017-04-05 26 views
0

我需要執行不同XML響應的XSL轉換,插入處理指令以幫助識別列表元素以便稍後進行XMLtoJSON轉換。包含xpaths的XSLT模板匹配參數

例輸入XML:

<?xml version="1.0" encoding="UTF-8"?> 
<recipe_collection> 
    <last_updated>20170405</last_updated> 
    <recipe> 
     <name>Split Pea Soup</name> 
     <ingredients_list> 
     <ingredient> 
      <name>Split Peas</name> 
      <amount>1 bag</amount> 
     </ingredient> 
     <ingredient> 
      <name>Vegetable Broth</name> 
      <amount>32 Ounces</amount> 
     </ingredient> 
     <ingredient> 
      <name>Vegetable Broth</name> 
      <amount>32 Ounces</amount> 
     </ingredient> 
     <ingredient> 
      <name>Ham</name> 
      <amount>Small</amount> 
     </ingredient> 
     </ingredients_list> 
     <preparation> 
     <step>Rinse Peas</step> 
     <step>Add ingredients to pressure cooker</step> 
     <step>Cook at full pressure for 12 minutes</step> 
     <step>Season with salt, pepper, garlic powder to taste</step> 
     </preparation> 
     <serve_with> 
     <name>Bread</name> 
     </serve_with> 
    </recipe> 
</recipe_collection> 

例XSL:

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

    <xsl:template match="node()|@*"> 
     <xsl:copy> 
     <xsl:apply-templates select="node()|@*" /> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="/recipe_collection/recipe/name[1]|/recipe_collection/recipe/ingredients_list/ingredient[1]|/recipe_collection/recipe/ingredients_list/ingredient[1]|/recipe_collection/recipe/preparation/step[1]|/recipe_collection/recipe/serve_with/name[1]"> 
     <xsl:processing-instruction name="xml-multiple"> 
     <xsl:value-of select="local-name()" /> 
     </xsl:processing-instruction> 
     <xsl:copy> 
     <xsl:apply-templates select="node()|@*" /> 
     </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

這反過來又會將原始的XML與<?xml-muliple ...?>督察插入:

<?xml version="1.0" encoding="UTF-8"?> 
<recipe_collection> 
    <last_updated>20170405</last_updated> 
    <recipe> 
     <?xml-multiple name?> 
     <name>Split Pea Soup</name> 
     <ingredients_list> 
     <?xml-multiple ingredient?> 
     <ingredient> 
      <name>Split Peas</name> 
      <amount>1 bag</amount> 
     </ingredient> 
     <ingredient> 
      <name>Vegetable Broth</name> 
      <amount>32 Ounces</amount> 
     </ingredient> 
     <ingredient> 
      <name>Vegetable Broth</name> 
      <amount>32 Ounces</amount> 
     </ingredient> 
     <ingredient> 
      <name>Ham</name> 
      <amount>Small</amount> 
     </ingredient> 
     </ingredients_list> 
     <preparation> 
     <?xml-multiple step?> 
     <step>Rinse Peas</step> 
     <step>Add ingredients to pressure cooker</step> 
     <step>Cook at full pressure for 12 minutes</step> 
     <step>Season with salt, pepper, garlic powder to taste</step> 
     </preparation> 
     <serve_with> 
     <?xml-multiple name?> 
     <name>Bread</name> 
     </serve_with> 
    </recipe> 
</recipe_collection> 

到目前爲止好。現在讓這個XSL用不同的XML模式工作。我想傳入一個包含比賽中使用的路徑的參數。

在修改樣式表,我定義參數「的XPath」與默認路徑列表中(注意,此PARAM值將實際運行時傳遞給XSL):

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

    <xsl:param name="xpaths">/recipe_collection/recipe/name[1]|/recipe_collection/recipe/ingredients_list/ingredient[1]|/recipe_collection/recipe/ingredients_list/ingredient[1]|/recipe_collection/recipe/preparation/step[1]|/recipe_collection/recipe/serve_with/name[1]</xsl:param> 

    <xsl:template match="node()|@*"> 
     <xsl:copy> 
     <xsl:apply-templates select="node()|@*" /> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="$xpaths"> 
     <xsl:processing-instruction name="xml-multiple"> 
     <xsl:value-of select="local-name()" /> 
     </xsl:processing-instruction> 
     <xsl:copy> 
     <xsl:apply-templates select="node()|@*" /> 
     </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

然而,在新的XSL的match="$xpaths"無效

其他注意事項:

我使用的XSL解析器允許XSL 2.0。

XSL必須適用於任何模式,包括元素可能沒有唯一名稱的模式,因此必須使用完整的xpath來指定列表。

最後,我作爲一個XSL newb道歉。讓我的大腦圍繞一些轉換概念,我仍然遇到困難。

感謝您在正確的方向(或解決方案)的任何指針。

回答

0

對於像Saxon 9.7 EE或PE這樣的XSLT 3.0處理器,您應該可以使用靜態變量和陰影屬性,例如

<xsl:param name="xpaths" static="yes" as="xs:string">/recipe_collection/recipe/name[1]|/recipe_collection/recipe/ingredients_list/ingredient[1]|/recipe_collection/recipe/ingredients_list/ingredient[1]|/recipe_collection/recipe/preparation/step[1]|/recipe_collection/recipe/serve_with/name[1]</xsl:param> 

    <xsl:template _match="{$xpaths}"> 
     <xsl:processing-instruction name="xml-multiple"> 
     <xsl:value-of select="local-name()" /> 
     </xsl:processing-instruction> 
     <xsl:copy> 
     <xsl:apply-templates select="node()|@*" /> 
     </xsl:copy> 
    </xsl:template> 

隨着純XSLT 2.0就需要使用一個樣式表把你的字符串路徑(S)作爲參數,將其輸出/生成與所述插入匹配的屬性值的期望的第二樣式表。

+0

謝謝。這在XML 3.0評估器中效果很好。不幸的是,我使用的工具Axway不僅限於XSLT 2.0或更低版本,它不允許您引用生成的樣式表。 我懷疑在2.0中可能有一種複雜的方法。我的另一種選擇是不使用Axway的XSLT處理器,並在您提到的Saxon中使用鉤子。 – user7822580