我有xml,以便我无法更改
<entry>
<sn>1 a</sn>
<dt>:to run away often from danger or evil</dt>
<sn>b</sn>
<dt>:to hurry toward a place of security</dt>
<sn>2</sn>
<dt>:to pass away swiftly</dt>
</entry>
我正在尝试编写XSLT以使其看起来像
<div class="entry">
<div class="def_group">
<span class="def_group_number">1</span>
<div class="def_value">
<span class="def_value_letter">a</span>
<span class="the_def">:to run away often from danger or evil</span>
</div>
<div class="def_value">
<span class="def_value_letter">b</span>
<span class="the_def">:to hurry toward a place of security</span>
</div>
</div>
<div class="def_group">
<span class="def_group_number">2</span>
<div class="def_value">
<span class="the_def">:to pass away swiftly</span>
</div>
</div>
</div>
当我分解时,我确实有两个问题。
如何使用XSLT 1.0,我是否将三种情况分开&lt;sn>("字母","数字","数字")?
,在包含一个数字的情况下,如何使用A&lt编写模板;Div>将包含其兄弟姐妹&lt;DT>小时候?
XSLT 1.0对于字符串操纵而言并不是很好,但我认为这可以做到。首先,我们将需要找到所有属于一个的字母sn
S,所以让我们定义一个键
<xsl:key name="subsenseByMainSense"
match="sn[not(number(substring(., 1, 1)) = number(substring(., 1, 1)))]"
use="generate-id(preceding-sibling::sn[
number(substring(., 1, 1)) = number(substring(., 1, 1))][1])" />
这看起来很奇怪,但这全是成语 - number() = number()
是一种检查所讨论的事物(这里是节点字符串值的第一个字符)的方法。如果您要检查的内容是一个数字,则测试正在检查一个数字是否相等,这始终是正确的;如果是不是 a数字,则测试是NaN = NaN
,始终为false。
现在从entry
开始,您需要一个以一个数字开头的sn
一个def_group
:
<xsl:template match="entry">
<div class="entry">
<xsl:apply-templates select="sn[number(substring(., 1, 1))
= number(substring(., 1, 1))]" />
</div>
</xsl:template>
<xsl:template match="sn">
<div class="def_group">
<span class="def_group_number">
<xsl:choose>
<xsl:when test="contains(., ' ')">
<xsl:value-of select="substring-before(., ' ')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="." />
</xsl:otherwise>
</xsl:choose>
</span>
<!-- do the value(s) of this element and any following letter-only ones -->
<xsl:apply-templates mode="value"
select=". | key('subsenseByMainSense', generate-id())" />
</div>
</xsl:template>
现在,对于值位,如果此元素有字母,则添加一个def_value_letter
,否则只有the_def
:
<xsl:template match="sn" mode="value">
<xsl:variable name="letter"
select="translate(., translate(., 'abcdefghijklmnopqrstuvwxyz', ''), '')" />
<div class="def_value">
<xsl:if test="$letter">
<span class="def_value_letter">
<xsl:value-of select="$letter" />
</span>
</xsl:if>
<span class="the_def">
<xsl:value-of select="following-sibling::dt[1]" />
</span>
</div>
</xsl:template>
双重翻译是另一个成语 - 这是一种从字符串中删除所有字符 的方法字符串。