如何将 xpath 与当前节点进行比较
how to compare xpath to current node
我正在使用 saxon 将 xml 转换为 xsl-fo。每个文件都有一个配套文件,其中包含已更改元素的 xpath。我需要将伴随文件中的 xpath 与当前节点进行比较。例如,如果当前正在处理的节点是 item8,那么根据伴随文件,它应该得到一个更改栏:
xml 文件
<body>
<unlist bulltype="NDASH" code="00019292.0001001.007" layer="1" lid="N.00019292.0001001.014">
<item layer="1">
<para layer="1" lid="N.00019292.0001001.015">item1</para>
</item>
<item layer="1">
<para layer="1" lid="N.00019292.0001001.018">item2</para>
</item>
<item layer="1">
<para layer="1" lid="N.00019292.0001001.019">item3</para>
</item>
<item layer="1">
<para layer="1" lid="N.00019292.0001001.020">item4</para>
</item>
<item layer="1">
<para layer="1" lid="N.00019292.0001001.021">item5</para>
</item>
<item layer="1">
<para layer="1" lid="N.00019292.0001001.022">item6</para>
</item>
<item layer="1">
<para layer="1" lid="N.00019292.0001001.023">item7</para>
</item>
<item layer="1">
<para layer="1" lid="N.00019292.0001001.024">item8</para>
</item>
<item layer="1">
<para layer="1" lid="N.00019292.0001001.025">item9</para>
</item>
<item layer="1">
<para layer="1" lid="N.00019292.0001001.026">item10</para>
</item>
</unlist>
</body>
配套文件
<rev-marks>
<rev anchor="false" chg="R" origin="airbus"
path="//*[@lid='N.00019292.0001001.014']/item[9]/para[1]"/>
<rev anchor="false" chg="R" origin="airbus"
path="//*[@lid='N.00019292.0001001.014']/item[8]/para[1]">
<hl-ref ref="hl_1"/>
</rev>
<rev anchor="true" chg="R" origin="airbus" path="//*[@lid='N.00019292.0001001.014']"/>
</rev-marks>
如果当前节点的路径与伴随文件中的 rev/@path 匹配,我基本上需要放置一个 fo 更改栏。任何帮助将不胜感激。
编辑以显示我目前所拥有的
<xsl:template match="para">
<!-- path of the current node -->
<xsl:variable name="curPath" select="saxon:path()"/>
<!-- path of the companion file -->
<xsl:variable name="mdata">../MU/<xsl:value-of select="ancestor::description/@code"/>_mdata.xml</xsl:variable>
<xsl:for-each select="document($mdata,.)//rev">
<!-- value of //rev/@path in the companion file -->
<xsl:variable name="revPath" select="@path"/>
<xsl:if test="$revPath = $curPath">
<fo:change-bar-begin change-bar-class="cbpara" change-bar-color="black" change-bar-style="solid" change-bar-offset="15pt"/>
</xsl:if>
</xsl:for-each>
<fo:block>
<xsl:apply-templates/>
</fo:block>
<!-- add fo:change-bar-end here -->
</xsl:template>
正是这条语句让我无法比较 2 个 xpath 表达式
希望这能说明问题
有两种通用方法。
一种是使用xsl:evaluate
计算配套文件中的XPath 表达式。确切的解决方案取决于需求的细节:例如,我不确定是否所有 <rev>
元素都以相同的方式处理,或者 @anchor
和 @rev
的意义是什么@origin
属性是。
第二种方法是编写一个转换,将您的伴随文件转换为执行实际工作的 XSLT 样式表(通常,每个 <rev>
元素都转换为具有匹配模式的 xsl:template
).这听起来有点令人生畏,但这可能是更优雅的方法。
使用 xsl:evaluate
的示例(Saxon 9.8 及更高版本的 PE 和 EE 版本、Saxon 10 所有版本以及 Saxon-JS 2 中支持)是:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="#all"
version="3.0">
<xsl:param name="rev-doc-uri" as="xs:string">evaluate-key-ref-marks.xml</xsl:param>
<xsl:param name="rev-doc" select="doc($rev-doc-uri)"/>
<xsl:function name="mf:select-node" as="node()*">
<xsl:param name="path" as="xs:string"/>
<xsl:param name="context-doc" as="node()"/>
<xsl:evaluate context-item="$context-doc" xpath="$path"/>
</xsl:function>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="*[some $rev in $rev-doc//rev[@path] satisfies (. is mf:select-node($rev/@path, /))]">
<xsl:comment>marked</xsl:comment>
<xsl:next-match/>
</xsl:template>
</xsl:stylesheet>
我正在使用 saxon 将 xml 转换为 xsl-fo。每个文件都有一个配套文件,其中包含已更改元素的 xpath。我需要将伴随文件中的 xpath 与当前节点进行比较。例如,如果当前正在处理的节点是 item8,那么根据伴随文件,它应该得到一个更改栏:
xml 文件
<body>
<unlist bulltype="NDASH" code="00019292.0001001.007" layer="1" lid="N.00019292.0001001.014">
<item layer="1">
<para layer="1" lid="N.00019292.0001001.015">item1</para>
</item>
<item layer="1">
<para layer="1" lid="N.00019292.0001001.018">item2</para>
</item>
<item layer="1">
<para layer="1" lid="N.00019292.0001001.019">item3</para>
</item>
<item layer="1">
<para layer="1" lid="N.00019292.0001001.020">item4</para>
</item>
<item layer="1">
<para layer="1" lid="N.00019292.0001001.021">item5</para>
</item>
<item layer="1">
<para layer="1" lid="N.00019292.0001001.022">item6</para>
</item>
<item layer="1">
<para layer="1" lid="N.00019292.0001001.023">item7</para>
</item>
<item layer="1">
<para layer="1" lid="N.00019292.0001001.024">item8</para>
</item>
<item layer="1">
<para layer="1" lid="N.00019292.0001001.025">item9</para>
</item>
<item layer="1">
<para layer="1" lid="N.00019292.0001001.026">item10</para>
</item>
</unlist>
</body>
配套文件
<rev-marks>
<rev anchor="false" chg="R" origin="airbus"
path="//*[@lid='N.00019292.0001001.014']/item[9]/para[1]"/>
<rev anchor="false" chg="R" origin="airbus"
path="//*[@lid='N.00019292.0001001.014']/item[8]/para[1]">
<hl-ref ref="hl_1"/>
</rev>
<rev anchor="true" chg="R" origin="airbus" path="//*[@lid='N.00019292.0001001.014']"/>
</rev-marks>
如果当前节点的路径与伴随文件中的 rev/@path 匹配,我基本上需要放置一个 fo 更改栏。任何帮助将不胜感激。
编辑以显示我目前所拥有的
<xsl:template match="para">
<!-- path of the current node -->
<xsl:variable name="curPath" select="saxon:path()"/>
<!-- path of the companion file -->
<xsl:variable name="mdata">../MU/<xsl:value-of select="ancestor::description/@code"/>_mdata.xml</xsl:variable>
<xsl:for-each select="document($mdata,.)//rev">
<!-- value of //rev/@path in the companion file -->
<xsl:variable name="revPath" select="@path"/>
<xsl:if test="$revPath = $curPath">
<fo:change-bar-begin change-bar-class="cbpara" change-bar-color="black" change-bar-style="solid" change-bar-offset="15pt"/>
</xsl:if>
</xsl:for-each>
<fo:block>
<xsl:apply-templates/>
</fo:block>
<!-- add fo:change-bar-end here -->
</xsl:template>
正是这条语句让我无法比较 2 个 xpath 表达式
希望这能说明问题
有两种通用方法。
一种是使用xsl:evaluate
计算配套文件中的XPath 表达式。确切的解决方案取决于需求的细节:例如,我不确定是否所有 <rev>
元素都以相同的方式处理,或者 @anchor
和 @rev
的意义是什么@origin
属性是。
第二种方法是编写一个转换,将您的伴随文件转换为执行实际工作的 XSLT 样式表(通常,每个 <rev>
元素都转换为具有匹配模式的 xsl:template
).这听起来有点令人生畏,但这可能是更优雅的方法。
使用 xsl:evaluate
的示例(Saxon 9.8 及更高版本的 PE 和 EE 版本、Saxon 10 所有版本以及 Saxon-JS 2 中支持)是:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="#all"
version="3.0">
<xsl:param name="rev-doc-uri" as="xs:string">evaluate-key-ref-marks.xml</xsl:param>
<xsl:param name="rev-doc" select="doc($rev-doc-uri)"/>
<xsl:function name="mf:select-node" as="node()*">
<xsl:param name="path" as="xs:string"/>
<xsl:param name="context-doc" as="node()"/>
<xsl:evaluate context-item="$context-doc" xpath="$path"/>
</xsl:function>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="*[some $rev in $rev-doc//rev[@path] satisfies (. is mf:select-node($rev/@path, /))]">
<xsl:comment>marked</xsl:comment>
<xsl:next-match/>
</xsl:template>
</xsl:stylesheet>