我有一个XML文档,它使用多个@class值,如下所示:
<html>
<head>
<title>This is the title.</title>
</head>
<body>
<div class="sect1 rights">
<p>This is the first paragraph.</p>
</div>
</body>
</html>
但是,如果存在@class值,则下面的XSLT不起作用。它只适用于<div class="rights">
。
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[@class='rights']">
<p>Rights have not cleared to show this material.</p>
</xsl:template>
我不认为这是模板问题的优先级(来自身份模板),因为我没有收到警告。有没有办法选择这个内容?除了“权利”之外,我不会总是知道除了“权限”之外还分配了哪些其他类值,因此我不能使用*[@class='sect1 rights']
,因为sect1将在整个文档中发生变化。
答案 0 :(得分:2)
在您的示例中,“class”属性只有单个值:字符串“sect1 rights”。如果要测试在该值中包含字符串“rights”,请使用:
<xsl:template match="*[contains(@class,'rights')]">
或者也许:
contains(concat(' ', @class, ' '), ' rights ')
如果您想确保“权利”作为一个单词存在(例如,不是“版权”的一部分)。
答案 1 :(得分:2)
由于您使用的是XSLT 2.0,因此可以使用tokenize()
。这是concat()
解决方案的一种更简单的形式@user3016153 gave(两种形式都比简单的contains()
准确得多)。
<xsl:template match="*[tokenize(@class,'\s')='rights']">
<p>Rights have not cleared to show this material.</p>
</xsl:template>
如果你想匹配多个可能的类,也很容易扩展:
<xsl:template match="*[tokenize(@class,'\s')=('rights','otherclass')]">
<p>Rights have not cleared to show this material.</p>
</xsl:template>