xsl:当两个节点相等时,显示第一个节点的子节点
xsl: when two nodes are equal, display child of first node
我正在使用 XML Editor 19.1,Saxon P.E 9.7。
对于每个选定的 div
,如果 surface/@xml:id
= div/@facs
,我希望在每个 <surface>
之后显示一个 graphic/@url
。
XSL
<xsl:for-each select="descendant-or-self::div3[@type='col']/div4[@n]">
<xsl:variable name="div4tablet" select="@facs"/>
<xsl:choose>
<xsl:when test="translate(.[@n]/$div4tablet, '#', '') = preceding::facsimile/surfaceGrp[@type='tablet']/surface[@n]/@xml:id">
<xsl:value-of select=""/> <!-- DISPLAY graphic/@url that follows facsimile/surfaceGrp/surface -->
</xsl:when>
<xsl:otherwise/>
</xsl:choose>
[....]
</xsl:for-each>
TEI
例子
<facsimile>
<surfaceGrp n="1" type="tablet">
<surface n="1.1" xml:id="ktu1-2_i_1_to_10_img">
<graphic url="../img/KTU-1-2-1-10-recto.jpg"/>
<zone xml:id=""/>
<zone xml:id=""/>
</surface>
<surface n="1.2" xml:id="ktu1-2_i_10_to_30_img">
<graphic url="../img/KTU-1-2-10-30-recto.jpg"/>
<zone xml:id=""/>
</surface>
[...]
</surfaceGrp>
<surfaceGrp n="2">
[...]
</surfaceGrp>
</facsimile>
<text>
[...]
<div3 type="col">
<div4 n="1.2.1-10" xml:id="ktu1-2_i_1_to_10" facs="#ktu1-2_i_1_to_10_img">
[...]
</div4>
<div4 n="1.2.10-30" xml:id="ktu1-2_i_10_to_30" facs="#ktu1-2_i_10_to_30_img">
[...]
</div4>
</div3>
</text>
我试过 <xsl:value-of select="preceding::facsimile/surfaceGrp[@type='tablet']/surface[@n, @xml:id]/graphic/@url"/>
,但它显示所有 graphic/@url
,而不仅仅是 fascsimile/surfaceGrp/surface
之后的那个。
所以我的问题是:如何为每个 div3[@type='col']/div4[@n]
?
只显示 surface/graphic/@url
预先感谢您的帮助。
您应该使用 xsl:key
解决此类问题。
首先,我们必须为目标节点声明一个键
<xsl:key name="kSurface" match="surface" use="concat('#', @xml:id)"/>
注意这里使用的 concat
函数,一个 # 被添加到 xml:id 以便键显示为:
#ktu1-2_i_1_to_10_img
#ktu1-2_i_10_to_30_img
现在在这个循环中:
<xsl:for-each select="descendant-or-self::div3[@type='col']/div4[@n]">
我们可以通过以下方式访问与 @facs
属性匹配的键:
<xsl:value-of select="key('kSurface', @facs)/graphic/@url"/>
整个样式表如下:
<?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"
exclude-result-prefixes="xs"
version="1.0">
<xsl:output omit-xml-declaration="yes"/>
<xsl:key name="kSurface" match="surface" use="concat('#', @xml:id)"/>
<xsl:template match="/">
<xsl:for-each select="descendant-or-self::div3[@type='col']/div4[@n]">
<xsl:value-of select="key('kSurface', @facs)/graphic/@url"/>
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
查看实际效果 here。
当您使用 XSLT 2 或 3 并且元素具有 xml:id
属性时,您甚至不需要键,但可以使用 id
函数:
<xsl:template match="div4">
<div>
<xsl:value-of select="id(substring(@facs, 2))/graphic/@url"/>
</div>
</xsl:template>
我将 id
的使用放入与 div4
元素匹配的模板中,但您当然可以在选择这些元素的 for-each
中以相同的方式使用它。
在 https://xsltfiddle.liberty-development.net/bdxtpR 查看最小但完整的示例。
我正在使用 XML Editor 19.1,Saxon P.E 9.7。
对于每个选定的 div
,如果 surface/@xml:id
= div/@facs
,我希望在每个 <surface>
之后显示一个 graphic/@url
。
XSL
<xsl:for-each select="descendant-or-self::div3[@type='col']/div4[@n]">
<xsl:variable name="div4tablet" select="@facs"/>
<xsl:choose>
<xsl:when test="translate(.[@n]/$div4tablet, '#', '') = preceding::facsimile/surfaceGrp[@type='tablet']/surface[@n]/@xml:id">
<xsl:value-of select=""/> <!-- DISPLAY graphic/@url that follows facsimile/surfaceGrp/surface -->
</xsl:when>
<xsl:otherwise/>
</xsl:choose>
[....]
</xsl:for-each>
TEI
例子
<facsimile>
<surfaceGrp n="1" type="tablet">
<surface n="1.1" xml:id="ktu1-2_i_1_to_10_img">
<graphic url="../img/KTU-1-2-1-10-recto.jpg"/>
<zone xml:id=""/>
<zone xml:id=""/>
</surface>
<surface n="1.2" xml:id="ktu1-2_i_10_to_30_img">
<graphic url="../img/KTU-1-2-10-30-recto.jpg"/>
<zone xml:id=""/>
</surface>
[...]
</surfaceGrp>
<surfaceGrp n="2">
[...]
</surfaceGrp>
</facsimile>
<text>
[...]
<div3 type="col">
<div4 n="1.2.1-10" xml:id="ktu1-2_i_1_to_10" facs="#ktu1-2_i_1_to_10_img">
[...]
</div4>
<div4 n="1.2.10-30" xml:id="ktu1-2_i_10_to_30" facs="#ktu1-2_i_10_to_30_img">
[...]
</div4>
</div3>
</text>
我试过 <xsl:value-of select="preceding::facsimile/surfaceGrp[@type='tablet']/surface[@n, @xml:id]/graphic/@url"/>
,但它显示所有 graphic/@url
,而不仅仅是 fascsimile/surfaceGrp/surface
之后的那个。
所以我的问题是:如何为每个 div3[@type='col']/div4[@n]
?
surface/graphic/@url
预先感谢您的帮助。
您应该使用 xsl:key
解决此类问题。
首先,我们必须为目标节点声明一个键
<xsl:key name="kSurface" match="surface" use="concat('#', @xml:id)"/>
注意这里使用的 concat
函数,一个 # 被添加到 xml:id 以便键显示为:
#ktu1-2_i_1_to_10_img
#ktu1-2_i_10_to_30_img
现在在这个循环中:
<xsl:for-each select="descendant-or-self::div3[@type='col']/div4[@n]">
我们可以通过以下方式访问与 @facs
属性匹配的键:
<xsl:value-of select="key('kSurface', @facs)/graphic/@url"/>
整个样式表如下:
<?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"
exclude-result-prefixes="xs"
version="1.0">
<xsl:output omit-xml-declaration="yes"/>
<xsl:key name="kSurface" match="surface" use="concat('#', @xml:id)"/>
<xsl:template match="/">
<xsl:for-each select="descendant-or-self::div3[@type='col']/div4[@n]">
<xsl:value-of select="key('kSurface', @facs)/graphic/@url"/>
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
查看实际效果 here。
当您使用 XSLT 2 或 3 并且元素具有 xml:id
属性时,您甚至不需要键,但可以使用 id
函数:
<xsl:template match="div4">
<div>
<xsl:value-of select="id(substring(@facs, 2))/graphic/@url"/>
</div>
</xsl:template>
我将 id
的使用放入与 div4
元素匹配的模板中,但您当然可以在选择这些元素的 for-each
中以相同的方式使用它。
在 https://xsltfiddle.liberty-development.net/bdxtpR 查看最小但完整的示例。