按值获取唯一的节点集,然后查看值的任何节点是否在XSLT 1.0中具有属性

时间:2016-08-18 18:34:41

标签: xml xslt xslt-1.0

我有现有的代码来获取给定类型节点的唯一值列表,但现在我想做一些特别的事情,如果具有特定值的任何节点具有特定属性。

示例XML:

<TopNode>
  <SampleNode>
    <Widget Special="True">Widget1</Widget>
    <Widget>Widget2</Widget>
  </SampleNode>
  <SampleNode>
    <Widget>Widget1</Widget>
  </SampleNode>
  <Widget>Widget3</Widget>
</TopNode>

注意:

  • <Widget>个节点可以出现在层次结构中的多个位置
  • Widget1应该在输出中得到特殊处理,因为它在其中一个位置具有Special属性。
  • 我不关心属性的值,只关注它是否存在给定值。
  • 我不希望Widget1在输出中显示两次,即使它有时具有属性,有时也没有。

以下是我(用于)获取唯一值的现有代码:

<xsl:key name="unique-widgets" match="//Widget" use="text()"/>
<xsl:for-each select="//Widget[count(. | key('unique-widgets', text())[1]) = 1]">
  <xsl:sort select="."/>
    <div class="widget-col">
      <xsl:apply-templates select="current()"/>
    </div>
</xsl:for-each>

以下是我最初尝试检查属性时只记得我不再有实际节点,而只是执行Muenchian分组后的文本值:

<xsl:key name="unique-widgets" match="//Widget" use="text()"/>
<xsl:for-each select="//Widget[count(. | key('unique-widgets', text())[1]) = 1]">
  <xsl:sort select="."/>
    <div class="widget-col">
      <xsl:if test="current()/@Special">
        <xsl:attribute name="class">
          widget-col special
        </xsl:attribute>
      </xsl:if>
      <xsl:apply-templates select="current()"/>
    </div>
</xsl:for-each>

预期产出:

<div class="widget special">Widget1</div>
<div class="widget">Widget2</div>
<div class="widget">Widget3</div>

是否可以将此信息作为XML分组的一部分收集?如果没有,那么查找每个值的最有效方法是什么?

2 个答案:

答案 0 :(得分:1)

Muenchian分组返回每个组的第一个节点(按文档顺序)。如果您想知道组中的任何节点是否具有特定属性,则需要再次使用该密钥才能查询该组:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" version="1.0" encoding="utf-8" indent="yes"/>

<xsl:key name="unique-widgets" match="Widget" use="." />

<xsl:template match="/">
    <xsl:for-each select="//Widget[count(. | key('unique-widgets', .)[1]) = 1]">
        <xsl:sort select="."/>
        <div class="widget-col">
            <xsl:if test="key('unique-widgets', .)/@Special">
                <xsl:attribute name="class">widget-col special</xsl:attribute>
            </xsl:if>
            <xsl:value-of select="."/>
        </div>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

答案 1 :(得分:0)

进行检查test="key('unique-widgets', .)/@Special"