寻找saxon:evaluate()示例代码

时间:2018-12-13 10:53:13

标签: xslt-2.0 saxon

我有一个transform.xsl文件,它将处理一个input.xml。但是,还有一个额外的config.xml文件将定义其他子句。例如这是config.xml的内容。

<Location >
  <DisplayName>
     <Attribute1>ABC</Attribute1>
     <Attribute2>XYZ</Attribute2>
     <action>concat($Attribute1,$Attribute2)</action>
  </DisplayName>
</Location >

因此,当transform.xsl在input.xml中遇到DisplayName变量时,它将与config.xml文件中定义的动作表达式的RESULT形成值。 transform.xml将调用config.xml只是为了获得结果。 (该操作可以由最终用户修改,因此将它们放置在config.xml中的xsl文件外部)。

我们正在使用saxon xml处理器版本9和xslt 2.0。因此,我们需要使用saxon:evaluate()。我试图找到更多saxon:evaluate()的示例,但找不到更多。谁能给我展示一些使用它的例子?

谢谢。

*****这是一个经过编辑的查询,着重强调了撒克逊人的需求:评估*****

2 个答案:

答案 0 :(得分:1)

以下是使用支持xsl:evaluatehttps://www.w3.org/TR/xslt-30/#dynamic-xpath)(即Saxon 9.8或更高版本以及商业PE或EE版本或Altova 2017或更高版本)的XSLT 3处理器的示例”文件:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:map="http://www.w3.org/2005/xpath-functions/map"
    xmlns:mf="http://example.com/mf"
    exclude-result-prefixes="#all"
    version="3.0">

    <xsl:param name="config-url" as="xs:string">test2018121301.xml</xsl:param>
    <xsl:param name="config-doc" select="doc($config-url)"/>

    <xsl:mode on-no-match="shallow-copy"/>

    <xsl:key name="element" match="*" use="node-name()"/>

    <xsl:function name="mf:config-evaluation" as="item()*">
        <xsl:param name="config-doc" as="document-node()"/>
        <xsl:param name="element-name" as="xs:QName"/>
        <xsl:variable name="display" select="key('element', $element-name, $config-doc)/DisplayName"/>
        <xsl:evaluate xpath="$display/regex" with-params="map:merge($display!(* except regex)!map { QName('', local-name()) : string() })"/>
    </xsl:function>

    <xsl:template match="*[key('element', node-name(), $config-doc)]">
        <xsl:copy>
            <xsl:value-of select="mf:config-evaluation($config-doc, node-name()), ."/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

因此使用config.xml

<Location >
    <DisplayName>
        <Attribute1>ABC</Attribute1>
        <Attribute2>XYZ</Attribute2>
        <regex>concat($Attribute1,$Attribute2)</regex>
    </DisplayName>
</Location >

这将例如使用

来转换输入样本
<Root>
    <Items>
        <Item>
            <Data>data 1</Data>
            <Location>location 1</Location>
        </Item>
        <Item>
            <Data>data 2</Data>
            <Location>location 2</Location>
        </Item>
    </Items>
</Root>

进入

<Root>
    <Items>
        <Item>
            <Data>data 1</Data>
            <Location>ABCXYZ location 1</Location>
        </Item>
        <Item>
            <Data>data 2</Data>
            <Location>ABCXYZ location 2</Location>
        </Item>
    </Items>
</Root>

这为您提供了极大的灵活性,允许在配置文件中使用XPath表达式,但是正如https://www.w3.org/TR/xslt-30/#evaluate-effect所指出的那样,这也是一个安全问题:“样式表作者需要意识到与使用xsl:evaluate。该指令不应用于从不受信任的来源执行代码。”。

对于使用不支持XSLT 3 saxon:evaluate指令的较早版本的Saxon支持的xsl:evaluate函数,

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:saxon="http://saxon.sf.net/"
    exclude-result-prefixes="#all"
    version="2.0">

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

    <xsl:template match="example">
        <xsl:copy>
            <xsl:value-of select="saxon:evaluate(@expression, @foo, @bar)"/>
        </xsl:copy>
    </xsl:template>   

</xsl:stylesheet>

转换输入

<root>
    <example expression="concat($p1, $p2)" foo="This is " bar="an example."/>
    <example expression="replace(., $p1, $p2)" foo="\p{L}" bar="X">This is example 2.</example>
</root>

进入结果

<root>
    <example>This is an example.</example>
    <example>XXXX XX XXXXXXX 2.</example>
</root>

答案 1 :(得分:0)

尝试检查xsl-attribute标签和xsl-value-of标签。如果我得到您的要求,则可能可以使用transform.xsl(或中间文件的第二个xsl)读取config.xml,以将regex标记内的文本设置为与标记属性的值相对应在xsl中。

https://www.w3schools.com/xml/ref_xsl_el_attribute.asp

此外,请在XSLT 2中查看本教程中的正则表达式,这可能会有所帮助:

https://www.xml.com/pub/a/2003/06/04/tr.html