XSLT: Как выбрать элементы, которые являются уникальными для предка (не корня)? - PullRequest
0 голосов
/ 17 февраля 2012

Я ищу способ выбрать уникальный набор узлов из элемента-предка ниже корня.Мой упрощенный ввод выглядит следующим образом (Примечание: в <Package> может быть несколько элементов <Single> и <Multi>):

<Package>
  <Single>
    <Patient>
      <Drug>
        <Name>A</Name>
        <Dose>1 tab</Dose>
      </Drug>
      <Drug>
        <Name>B</Name>
        <Dose>2 spoonfuls</Dose>
      </Drug>
    </Patient>
  </Single>
  <Multi>
    <Patient>
      <Drug>
        <Name>A</Name>
        <Dose>1 tab</Dose>
      </Drug>
      <Drug>
        <Name>B</Name>
        <Dose>2 spoonfuls</Dose>
      </Drug>
      <Drug>
        <Name>C</Name>
        <Dose>3 drops</Dose>
      </Drug>
    </Patient>
    <Patient>
      <Drug>
        <Name>B</Name>
        <Dose>2 spoonfuls</Dose>
      </Drug>
      <Drug>
        <Name>B</Name>
        <Dose>2 spoonfuls</Dose>
      </Drug>
      <Drug>
        <Name>C</Name>
        <Dose>3 drops</Dose>
      </Drug>
      <Drug>
        <Name>D</Name>
        <Dose>4 glasses</Dose>
      </Drug>
    </Patient>
  </Multi>
</Package>

Я бы хотел выбрать лекарства, уникальные для каждого<Single> или <Multi> элемент по <Patient> с.Пока у меня есть:

  <xsl:template match="/">
    <xsl:for-each select="Package/Single | Package/Multi">
      <xsl:call-template name="SO" />
    </xsl:for-each>
  </xsl:template>

  <xsl:key name="uniqueKey" match="//Patient/Drug" use="concat(Name, Dose)" />

  <xsl:template name="SO">
    <UniquePerMultiOrSingle>
      <xsl:for-each select="//Patient/Drug[
                              generate-id() =
                              generate-id(key('uniqueKey', concat(Name, Dose))[1])]">
        <xsl:copy-of select="Name"/>
        <xsl:copy-of select="Dose"/>
      </xsl:for-each>
    </UniquePerMultiOrSingle>
  </xsl:template>

Вывод выглядит так:

<UniquePerMultiOrSingle>
  <Name>A</Name>
  <Dose>1 tab</Dose>
  <Name>B</Name>
  <Dose>2 spoonfuls</Dose>
  <Name>C</Name>
  <Dose>3 drops</Dose>
  <Name>D</Name>
  <Dose>4 glasses</Dose>
</UniquePerMultiOrSingle>
<UniquePerMultiOrSingle>
  <Name>A</Name>
  <Dose>1 tab</Dose>
  <Name>B</Name>
  <Dose>2 spoonfuls</Dose>
  <Name>C</Name>
  <Dose>3 drops</Dose>
  <Name>D</Name>
  <Dose>4 glasses</Dose>
</UniquePerMultiOrSingle>

Желаемый вывод должен выглядеть следующим образом:

<UniquePerMultiOrSingle>
  <Name>A</Name>
  <Dose>1 tab</Dose>
  <Name>B</Name>
  <Dose>2 spoonfuls</Dose>
</UniquePerMultiOrSingle>
<UniquePerMultiOrSingle>
  <Name>A</Name>
  <Dose>1 tab</Dose>
  <Name>B</Name>
  <Dose>2 spoonfuls</Dose>
  <Name>C</Name>
  <Dose>3 drops</Dose>
  <Name>D</Name>
  <Dose>4 glasses</Dose>
</UniquePerMultiOrSingle>

Мой вопрос: естьЕсть ли способ выбрать <Drug> с уникальными для <Single> или <Multi> только для элемента (не весь документ)?Если нет, есть ли другой способ добиться этого?Я использую xslt 1.0.

1 Ответ

0 голосов
/ 18 февраля 2012

Это преобразование :

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

 <xsl:key name="kPackageDrugsByName" match="Drug"
  use="concat(generate-id(../..), '+', Name, '+', Dose)"/>

 <xsl:template match="Single | Multi">
  <xsl:text>&#xA;</xsl:text>
  <xsl:value-of select="name()"/> -- Drugs:&#xA;<xsl:text/>

  <xsl:copy-of select=
   "*/Drug
       [generate-id()
       =
        generate-id(key('kPackageDrugsByName',
                        concat(generate-id(../..),
                               '+', Name, '+', Dose)
                       )[1]
                   )
       ]/*"/>
 </xsl:template>
</xsl:stylesheet>

при применении к предоставленному XML-документу :

<Package>
    <Single>
        <Patient>
            <Drug>
                <Name>A</Name>
                <Dose>1 tab</Dose>
            </Drug>
            <Drug>
                <Name>B</Name>
                <Dose>2 spoonfuls</Dose>
            </Drug>
        </Patient>
    </Single>
    <Multi>
        <Patient>
            <Drug>
                <Name>A</Name>
                <Dose>1 tab</Dose>
            </Drug>
            <Drug>
                <Name>B</Name>
                <Dose>2 spoonfuls</Dose>
            </Drug>
            <Drug>
                <Name>C</Name>
                <Dose>3 drops</Dose>
            </Drug>
        </Patient>
        <Patient>
            <Drug>
                <Name>B</Name>
                <Dose>2 spoonfuls</Dose>
            </Drug>
            <Drug>
                <Name>B</Name>
                <Dose>2 spoonfuls</Dose>
            </Drug>
            <Drug>
                <Name>C</Name>
                <Dose>3 drops</Dose>
            </Drug>
            <Drug>
                <Name>D</Name>
                <Dose>4 glasses</Dose>
            </Drug>
        </Patient>
    </Multi>
</Package>

создает искомое, правильный результат :

Single -- Drugs:
<Name>A</Name>
<Dose>1 tab</Dose>
<Name>B</Name>
<Dose>2 spoonfuls</Dose>

Multi -- Drugs:
<Name>A</Name>
<Dose>1 tab</Dose>
<Name>B</Name>
<Dose>2 spoonfuls</Dose>
<Name>C</Name>
<Dose>3 drops</Dose>
<Name>D</Name>
<Dose>4 glasses</Dose>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...