如何检查祖先是否是他祖先中该类型的最后一个元素

时间:2011-12-22 12:37:06

标签: xslt xpath

我有以下XML:

<TABLE>
  <ROW>
    <ENTRY/>
    <ENTRY/>
  </ROW>
  <ROW>
    <ENTRY>xxx</ENTRY>
    <ENTRY>yyy</ENTRY>
  </ROW>
  <Z>
    <ROW>
      <ENTRY/>
      <ENTRY/>
    </ROW>
  </Z>
  <ROW>
    <ENTRY/>
    <ENTRY/>
  </ROW>
</TABLE>

表结构可以改变,所以我可以将最后一行包裹在Z元素中,或者根本没有Z元素。

我的目标是删除表格最后一行条目中的下边框。 (TABLE映射到HTML表,ROW到HTML tr,ENTRY到HTML td)

所以我尝试使用xslt模板:

<xsl:template match="ENTRY">
  <td>
    <xsl:if test="(ancestor::ROW[1] = ancestor::TABLE[1]/descendant::ROW[last()])">
      <!-- remove the bottom border of td -->
    </xsl:if>  
  </td>
</xsl:template>

但它删除了表格中几乎所有单元格的边框(边框未从具有文本内容的单元格中删除)。所以我想机制检查节点是否具有相同的值(名称,文本内容,子项等) - 而不是引用。 我试图在java中使用一些外部函数,但我总是得到一个新的节点引用(即使对于相同的节点),所以我无法比较它。

所以我的问题是 - 如何比较节点的引用... 或以任何其他方式完成工作。

提前致谢:)。

2 个答案:

答案 0 :(得分:4)

  

我的目标是删除最后一行条目中的下边框   表。 (TABLE映射到HTML表,ROW到HTML tr,ENTRY到HTML td)

您似乎想要

<xsl:if test=
  "generate-id(ancestor::ROW[1]) 
  = 
   generate-id(ancestor::TABLE[1]/descendant::ROW[last()])">

  <!-- Processing here -->
</xsl:if>

我建议你添加一个新模板并使用模式匹配(而不是显式条件)来捕获这种情况:

<xsl:template match=
"ENTRY[generate-id(ancestor::ROW[1]) 
      = 
       generate-id(ancestor::TABLE[1]/descendant::ROW[last()])
      ]">

      <!-- Processing here -->
</xsl:template>

您更普遍的问题:

  

所以我的问题是 - 如何比较节点的引用

在XPath 2.0(XSLT 2.0)中使用is运算符

$n1 is $n2

测试两个节点$n1$n2以获取节点标识(而不是值相等)。

在XPath 1.0(XSLT 1.0)中:

count($n1|$n2) = 1

XSLT 1.0中的另一种方法是使用标准的XSLT 1.0(在XPath 1.0中不可用)函数 generate-id() ,如上面的解决方案中所做的那样:

generate-id($n1) = generate-id($n2)

答案 1 :(得分:0)

您的测试(ancestor::ROW[1] = ancestor::TABELA[1]/descendant::ROW[last()])与样本中的前两个和最后两个ENTRY元素相匹配。大概是因为当呈现为字符串时,第一个ROW与最后一个ROW匹配。见http://www.w3.org/TR/xpath/#booleans

我可以使用以下方式选择最后两个条目:

//ENTRY[count(ancestor::ROW[1]/preceding::ROW) = count(ancestor::TABLE[1]/descendant::ROW) - 1]

所以我想以下内容可以作为您的测试:

(count(ancestor::ROW[1]/preceding::ROW) = count(ancestor::TABLE[1]/descendant::ROW) - 1)

更新 感谢Dimitre Novatchev和jasso提供的反馈

此解决方案不理想:

  1. 这些计数效率低下,计算的数量超出必要的数量。
  2. 当较大文档的一部分时,
  3. preceding::轴可能不仅仅匹配TABLE元素的后代。