我需要对不同的XML响应进行XSL转换,插入处理指令以帮助识别列表元素,以便以后进行XMLtoJSON转换。
示例输入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 ...?>
PI复制:
<?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模式。我想传入一个包含匹配中使用的路径的参数。
在修改后的样式表中,我定义了参数&#34; xpaths&#34;使用默认路径列表(注意,此参数的值实际上将在运行时传递给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新手而道歉。我仍然无法绕过一些转换概念。
感谢您指出正确的方向(或解决方案)。
答案 0 :(得分: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,您需要使用一个样式表,将您的字符串路径作为参数,然后使用插入的匹配属性值输出/生成所需的第二个样式表。