Выбор отдельных значений из подзапроса XSLT - PullRequest
0 голосов
/ 17 октября 2018

У меня есть этот 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 голосов
/ 17 октября 2018

Ключи могут быть вашими друзьями здесь ...

<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;" />
0 голосов
/ 17 октября 2018

Ах, просто нужно попытаться немного усерднее:

<?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/groups/group[@name=$docRoot/metadata/types/type[@name=$docRoot/metadata/properties/property/@type]/@group]/@owner)">
      <xsl:value-of select="current()"/><xsl:text>
</xsl:text>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

Открыты для любых предложений по упрощению этого!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...