我有一个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()的示例,但找不到更多。谁能给我展示一些使用它的例子?
谢谢。
*****这是一个经过编辑的查询,着重强调了撒克逊人的需求:评估*****
答案 0 :(得分:1)
以下是使用支持xsl:evaluate
(https://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中查看本教程中的正则表达式,这可能会有所帮助: