我有一些看起来像这样的XML:
<section class="DoCO:Section">
<h1 class="DoCO:SectionTitle" id="42" page="3" column="2">EXPERIMENT</h1>
<region class="DoCO:TextChunk" id="43" page="3" column="2">lots of body<xref ref-type="bibr" rid="R7" id="35" class="deo:Reference">7</xref> text</region>
<region class="DoCO:FigureBox" id="F4">
<image class="DoCO:Figure" src="2cn.page_003.image_04.png" thmb="2cn.page_003.image_04-thumb.png"/>
<caption class="deo:Caption" id="44" page="3" column="2">Figure 4: Experimental Setup</caption>
</region>
我一直在使用以下XSL来分别匹配外部参照元素:
<xsl:for-each select="article/body/section">
<sec>
<xsl:for-each select="h1">
<title>
<xsl:value-of select="string(.)"/>
</title>
</xsl:for-each>
<xsl:for-each select="region">
<p>
<xsl:apply-templates/>
</p>
</xsl:for-each>
</xsl:template>
<xsl:template match="xref">
<xref/>
</xsl:template>
但是,我希望能够在给定区域内将图像和标题元素组合在一起,而无需更改当前处理区域元素的开放式方式,因此我尝试执行以下操作:
<xsl:template match="@class[.='DoCO:FigureBox']">
<fig xmlns:xlink="http://www.w3.org/1999/xlink">
<graphic>
<xsl:for-each select="image">
<xsl:attribute name="xlink:href">
<xsl:value-of select="@src"/>
</xsl:attribute>
</xsl:for-each>
</graphic>
<caption>
<xsl:for-each select="caption">
<xsl:value-of select="string(.)"/>
</xsl:for-each>
</caption>
</fig>
</xsl:template>
但匹配=“@ class [。='DoCO:FigureBox']”似乎没有被解雇。是否无法匹配xsl:apply-templates的父元素的属性,就像在子元素上匹配一样?
谢谢!
答案 0 :(得分:2)
以下语法没有错误:
<xsl:template match="@class[.='DoCO:FigureBox']">
你的(第一个)问题,就在这里
<xsl:apply-templates/>
这是此
的简写<xsl:apply-templates select="node()" />
这意味着,您没有选择任何属性,因此不会调用 @class 属性的模板匹配项。
现在,您可以将其更改为此
<xsl:apply-templates select="@*|node()" />
但这导致了第二个问题。在匹配 @class 的模板中,您有一些 xsl:for-each 语句,图片和标题。但此时,您位于 @class 属性,而不是区域元素,因此这些 xsl:for-each 语句将一无所获。
您可能应该做的是,不要在主代码中执行<xsl:for-each select="region">
,而是执行<xsl:apply-templates select="region" />
。然后,您可以有两个模板,如此
<xsl:template match="region">
<p>
<xsl:apply-templates />
</p>
</xsl:template>
<xsl:template match="region[@class='DoCO:FigureBox']">
<fig xmlns:xlink="http://www.w3.org/1999/xlink">
<graphic>
<xsl:for-each select="image">
<xsl:attribute name="xlink:href">
<xsl:value-of select="@src"/>
</xsl:attribute>
</xsl:for-each>
</graphic>
<caption>
<xsl:for-each select="caption">
<xsl:value-of select="string(.)"/>
</xsl:for-each>
</caption>
</fig>
</xsl:template>
在这种情况下,XSLT处理器应优先考虑更具体的模板,因此它将覆盖您对区域元素的默认处理。
事实上,如果您每个地区总是有一个字幕和图片,您可以将模板简化为:
<xsl:template match="region[@class='DoCO:FigureBox']">
<fig xmlns:xlink="http://www.w3.org/1999/xlink">
<graphic xlink:href="{@src}" />
<caption>
<xsl:value-of select="caption" />
</caption>
</fig>
</xsl:template>
请注意在创建属性时使用属性值模板。花括号表示要评估的表达式,而不是按字面输出。