【问题标题】:Get unique set of nodes by value, then see if any nodes for a value have attribute in XSLT 1.0按值获取唯一的节点集,然后查看某个值的任何节点是否具有 XSLT 1.0 中的属性
【发布时间】:2016-08-18 18:34:40
【问题描述】:

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

示例 XML:

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

注意事项:

  • &lt;Widget&gt; 节点可以出现在层次结构中的多个位置
  • 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 分组的一部分来收集?如果没有,查找每个值的最有效方法是什么?

【问题讨论】:

    标签: xml xslt xslt-1.0


    【解决方案1】:

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

    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>
    

    【讨论】:

    • 完美。感谢您清理我的密钥定义。
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-16
      • 2013-10-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-03
      相关资源
      最近更新 更多