XSLT:将元素名称作为字符串传递,并将其转换为XPATH表达式



XSLT3.0是否可以将字符串转换为XPATH查询中的元素名称?我想将元素的名称作为字符串传递给模板,然后在XPATH表达式中包含元素的名称。类似于<xsl:variable name="el-name" select="'p'"/><xsl:copy-of select="$el-name"/>,其中el-name不再是字符串,而是选择元素p。假设我有一个这样的源文档:

<?xml version="1.0" encoding="UTF-8"?>
<text xmlns="">
    <list xml:id="p-1">
        <item n="1"/>
        <item n="2"/>
    </list>
    <head>This is a heading</head>
    <p xml:id="p-1">Lorem ipsum</p>
    <p xml:id="p-2">dolorosum</p>
</text>

还有这样一个样式表:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xpath-default-namespace="" exclude-result-prefixes="xs" xmlns="">
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="/text">
        <selection-of-text xmlns="">
            <xsl:call-template name="get-elements">
                <xsl:with-param name="element-name" as="xs:string" select="'list'"/>
            </xsl:call-template>
            <xsl:call-template name="get-elements">
                <xsl:with-param name="element-name" as="xs:string" select="'p'"/>
            </xsl:call-template>
        </selection-of-text>
    </xsl:template>
    <xsl:template name="get-elements">
        <xsl:param name="element-name"/>
        <xsl:choose>
            <xsl:when test="$element-name = 'list'">
                <xsl:copy-of select="list"/>
            </xsl:when>
            <xsl:when test="$element-name = 'p'">
                <xsl:copy-of select="p"/>
            </xsl:when>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

在BASH中,我运行

java -cp "/mnt/c/Tools/SaxonHE9-9-1-4J/saxon9he.jar" net.sf.saxon.Transform 
-s:source.xml -xsl:stylesheet.xslt -o:output.xml

并获得所需的输出:

<?xml version="1.0" encoding="UTF-8"?>
<selection-of-text>
    <list xml:id="p-1">
        <item n="1"/>
        <item n="2"/>
    </list>
    <p xml:id="p-1">Lorem ipsum</p>
    <p xml:id="p-2">dolorosum</p>
</selection-of-text>

我的代码可以工作,但很笨拙。我想xsl:evaluate可能会动态构建正确的XPATH表达式,但我不知道如何构建。https://www.w3.org/TR/xslt-30/#evaluate-影响

正如Martin Honnen在上面友好地解释的那样,一个简单而简短的解决方案是:

<xsl:template name="get-elements">
    <xsl:param name="element-name"/>
    <xsl:copy-of select="*[name() = $element-name]"/>
</xsl:template>

我用Saxon PE 9.9.1.4测试的另一种解决方案是:

<xsl:template name="get-elements">
    <xsl:param name="element-name"/>
    <xsl:variable name = "els">
        <xsl:evaluate xpath="$element-name" context-item="."/>
    </xsl:variable>
    <xsl:copy-of select="$els"/>
</xsl:template>

最新更新