每个 XSLT 2.0 参数 list/map
XSLT 2.0 paramer list/map with for each
这是我的 xslt 文件:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xpath-default-namespace="http://xmlns.jcp.org/xml/ns/persistence">
<xsl:param name="childPath"/>
<xsl:param name="childNode"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[local-name()=$childNode]">
<xsl:apply-templates select="document($childPath)//class"/>
</xsl:template>
</xsl:stylesheet>
我的想法是我有一个父(模板)xml 文件和 N 个子 xml 文件。因此,我采用父级并为第一个子 xml 文件调用此 xslt 文件,为第二个子文件调用,依此类推。我使用 maven-xml-plugin 调用这个 xslt 文件,每次调用我都需要设置相当冗长的 transormationSet。
因此,我只想调用此 xslt 文件一次并将所有参数作为列表或地图传递。例如
$childNodes = nodeOne;nodeTwo;nodeThree
$childPaths = pathOne;pathTwo;pathTree
或点赞地图:
$children = nodeOne:pathOne;nodeTwo:pathTwo
谁能告诉我如何让我的 xslt 文件使用这样的 list/map 参数?
一种方法是引入模板模式并迭代名称/路径对
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xpath-default-namespace="http://xmlns.jcp.org/xml/ns/persistence">
<xsl:param name="children" select="'name1:path1;name2:path2'"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:variable name="here" select="."/>
<xsl:for-each select="tokenize($children,';')">
<xsl:apply-templates mode="child" select="$here">
<xsl:with-param name="name" tunnel="true" select="tokenize(.,':')[1]"/>
<xsl:with-param name="path" tunnel="true" select="tokenize(.,':')[2]"/>
</xsl:apply-templates>
</xsl:for-each>
</xsl:template>
<xsl:template match="*" mode="child">
<xsl:param name="name" tunnel="true"/>
<xsl:param name="path" tunnel="true"/>
<xsl:if test="local-name()=$name">
<xsl:apply-templates select="document($path)//class"/>
</xsl:if>
<xsl:apply-templates mode="child"/>
</xsl:template>
</xsl:stylesheet>
使用 XPath 3.1/XSLT 3.0 地图,如 Saxon 9.8 及更高版本或 Saxon-JS 2 或 Altova XML 2017 R3 及更高版本所支持,您可以使用
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:map="http://www.w3.org/2005/xpath-functions/map"
exclude-result-prefixes="#all"
expand-text="yes">
<xsl:param name="children" as="map(xs:string, xs:string)" select="map { 'nodeOne' : 'pathOne', 'nodeTwo' : 'pathTwo' }"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="*[local-name()=map:keys($children)]">
<xsl:apply-templates select="document($children(local-name()))//class"/>
</xsl:template>
</xsl:stylesheet>
作为坚持使用包含以分号分隔的值列表的字符串值的替代方法:
<xsl:param name="childNodes">nodeOne;nodeTwo;nodeThree</xsl:param>
<xsl:param name="childPaths">pathOne;pathTwo;pathTree</xsl:param>
<xsl:variable name="childNodesSeq" select="tokenize($childNodes, ';')"/>
<xsl:variable name="childPathsSeq" select="tokenize($childPaths, ';')"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="*[local-name()=$childNodesSeq]">
<xsl:apply-templates select="document($childPathsSeq[index-of($childNodesSeq, local-name(current()))])//class"/>
</xsl:template>
这是我的 xslt 文件:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xpath-default-namespace="http://xmlns.jcp.org/xml/ns/persistence">
<xsl:param name="childPath"/>
<xsl:param name="childNode"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[local-name()=$childNode]">
<xsl:apply-templates select="document($childPath)//class"/>
</xsl:template>
</xsl:stylesheet>
我的想法是我有一个父(模板)xml 文件和 N 个子 xml 文件。因此,我采用父级并为第一个子 xml 文件调用此 xslt 文件,为第二个子文件调用,依此类推。我使用 maven-xml-plugin 调用这个 xslt 文件,每次调用我都需要设置相当冗长的 transormationSet。
因此,我只想调用此 xslt 文件一次并将所有参数作为列表或地图传递。例如
$childNodes = nodeOne;nodeTwo;nodeThree
$childPaths = pathOne;pathTwo;pathTree
或点赞地图:
$children = nodeOne:pathOne;nodeTwo:pathTwo
谁能告诉我如何让我的 xslt 文件使用这样的 list/map 参数?
一种方法是引入模板模式并迭代名称/路径对
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xpath-default-namespace="http://xmlns.jcp.org/xml/ns/persistence">
<xsl:param name="children" select="'name1:path1;name2:path2'"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:variable name="here" select="."/>
<xsl:for-each select="tokenize($children,';')">
<xsl:apply-templates mode="child" select="$here">
<xsl:with-param name="name" tunnel="true" select="tokenize(.,':')[1]"/>
<xsl:with-param name="path" tunnel="true" select="tokenize(.,':')[2]"/>
</xsl:apply-templates>
</xsl:for-each>
</xsl:template>
<xsl:template match="*" mode="child">
<xsl:param name="name" tunnel="true"/>
<xsl:param name="path" tunnel="true"/>
<xsl:if test="local-name()=$name">
<xsl:apply-templates select="document($path)//class"/>
</xsl:if>
<xsl:apply-templates mode="child"/>
</xsl:template>
</xsl:stylesheet>
使用 XPath 3.1/XSLT 3.0 地图,如 Saxon 9.8 及更高版本或 Saxon-JS 2 或 Altova XML 2017 R3 及更高版本所支持,您可以使用
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:map="http://www.w3.org/2005/xpath-functions/map"
exclude-result-prefixes="#all"
expand-text="yes">
<xsl:param name="children" as="map(xs:string, xs:string)" select="map { 'nodeOne' : 'pathOne', 'nodeTwo' : 'pathTwo' }"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="*[local-name()=map:keys($children)]">
<xsl:apply-templates select="document($children(local-name()))//class"/>
</xsl:template>
</xsl:stylesheet>
作为坚持使用包含以分号分隔的值列表的字符串值的替代方法:
<xsl:param name="childNodes">nodeOne;nodeTwo;nodeThree</xsl:param>
<xsl:param name="childPaths">pathOne;pathTwo;pathTree</xsl:param>
<xsl:variable name="childNodesSeq" select="tokenize($childNodes, ';')"/>
<xsl:variable name="childPathsSeq" select="tokenize($childPaths, ';')"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="*[local-name()=$childNodesSeq]">
<xsl:apply-templates select="document($childPathsSeq[index-of($childNodesSeq, local-name(current()))])//class"/>
</xsl:template>