从XSLT子查询中选择不同的值

时间:2018-10-17 15:36:56

标签: xslt

我有这个XML文档:

<?xml version="1.0" encoding="UTF-8"?>
<metadata>
  <properties>
    <property name="prop1" type="type1"/>
    <property name="prop2" type="type2"/>
    <property name="prop3" type="type3"/>
    <property name="prop4" type="type1"/>
  </properties>
  <types>
    <type name="type1" group="group1"/>
    <type name="type2" group="group1"/>
    <type name="type3" group="group2"/>
    <type name="type4" group="group3"/>
  </types>
  <groups>
    <group name="group1" owner="owner1"/>
    <group name="group2" owner="owner2"/>
    <group name="group3" owner="owner3"/>
  </groups>
</metadata>

我正在使用此XSLT对其进行转换:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
    <xsl:variable name="docRoot" select="/" />
    <xsl:for-each select="distinct-values($docRoot/metadata/properties/property/@type)">
      <xsl:variable name="groupOwner" select="$docRoot/metadata/groups/group[@name=$docRoot/metadata/types/type[@name=current()]/@group]/@owner" />
      <xsl:value-of select="$groupOwner"/><xsl:text>
</xsl:text>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

我要做的是为文档中的所有属性打印出唯一组所有者的列表。我已经成功地使用distinct-values过滤出重复类型,但是看不到如何过滤出重复所有者。

当前输出:

owner1
owner1
owner2

所需的输出:

owner1
owner2

如果有帮助,没有两个组具有相同的所有者。

2 个答案:

答案 0 :(得分:3)

钥匙可以在这里成为您的朋友...

<xsl:key name="types" match="type" use="@name" />
<xsl:key name="groups" match="group" use="@name" />

然后您就可以执行此操作,甚至不需要distinct-values,因为您不会以这种方式返回重复的节点:

<xsl:for-each select="key('groups', key('types', metadata/properties/property/@type)/@group)">

例如,尝试使用此XSLT

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" />

  <xsl:key name="types" match="type" use="@name" />
  <xsl:key name="groups" match="group" use="@name" />

  <xsl:template match="/">
    <xsl:for-each select="key('groups', key('types', metadata/properties/property/@type)/@group)">
      <xsl:value-of select="concat(@owner, '&#10;')" />
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

实际上,您可以将xsl:for-each简化为:

<xsl:value-of select="key('groups', key('types', metadata/properties/property/@type)/@group)/@owner" separator="&#10;" />

答案 1 :(得分:1)

啊,只需要再努力一点:

require analytic 
require transport unless defined?(DISABLE_TRANSPORT) && DISABLE_TRANSPORT
require marketing
...

module FruitChain
end

欢迎打开任何简化建议!