Найти отдельный элемент дочернего элемента для каждого элемента с помощью xpath - PullRequest
0 голосов
/ 15 апреля 2020

Я просто заблудился при использовании xsl1.0. Я пытаюсь получить отчетливый вывод каждой 'строки', когда данные разбиты на несколько дочерних элементов.

Предоставлен этот источник данных ..

<?xml version="1.0" encoding="utf-8"?>
<Root>
  <row>
    <data>
      <a>
        <b>
          <c>
            <Vehicle>
              <ManufacturerName>BM</ManufacturerName>
            </Vehicle>
          </c>
          <c>
            <Vehicle>
              <ManufacturerName>FORD</ManufacturerName>
            </Vehicle>
          </c>
          <c>
            <Vehicle>
              <ManufacturerName>VAUXHALL</ManufacturerName>
            </Vehicle>
          </c>
          <c>
            <Vehicle>
              <ManufacturerName>VAUXHALL</ManufacturerName>
            </Vehicle>
          </c>
        </b>
      </a>
      <a>
        <b>
          <c>
            <Vehicle>
              <ManufacturerName>VAUXHALL</ManufacturerName>
            </Vehicle>
          </c>
          <c>
            <Vehicle>
              <ManufacturerName>ALPHA</ManufacturerName>
            </Vehicle>
          </c>
          <c>
            <Vehicle>
              <ManufacturerName>BRAVO</ManufacturerName>
            </Vehicle>
          </c>
        </b>
      </a>
    </data>
  </row>
  <row>
    <data>
      <a>
        <b>
          <c>
            <Vehicle>
              <ManufacturerName>CHARLIE</ManufacturerName>
            </Vehicle>
          </c>
          <c>
            <Vehicle>
              <ManufacturerName>ALPHA</ManufacturerName>
            </Vehicle>
          </c>
          <c>
            <Vehicle>
              <ManufacturerName>VAUXHALL</ManufacturerName>
            </Vehicle>
          </c>
        </b>
      </a>
      <a>
        <b>
          <c>
            <Vehicle>
              <ManufacturerName>BM</ManufacturerName>
            </Vehicle>
          </c>
          <c>
            <Vehicle>
              <ManufacturerName>ALPHA</ManufacturerName>
            </Vehicle>
          </c>
        </b>
      </a>
    </data>
  </row>
</Root>

Я хочу получить вывод, который выглядит следующим образом.

BM, FORD, VAUXHALL, ALPHA, BRAVO,
CHARLIE, ALPHA, VAUXHALL, BM,

Извините, если раньше об этом спрашивали, но я не мог понять, как выбрать отличительный значения для каждой строки. Мои текущие результаты показывают только значения в первой строке, а любые повторяющиеся значения в других строках не отображаются.

Любая помощь будет принята с благодарностью.

В настоящее время мой xsl

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

  <xsl:template match="Root">
  <xsl:apply-templates select="row"/>  

  </xsl:template>

  <xsl:template match="row">
  <xsl:apply-templates select="data/a/b/c/Vehicle[not(ManufacturerName=preceding::Vehicle/ManufacturerName)]"/>  
  <xsl:text>&#xA;</xsl:text>
  </xsl:template>

  <xsl:template match="data/a/b/c/Vehicle">
    <xsl:value-of select="ManufacturerName"/>
    <xsl:text>,</xsl:text>
  </xsl:template>
</xsl:stylesheet>

с таким результатом.

BM,FORD,VAUXHALL,ALPHA,BRAVO,
CHARLIE,

1 Ответ

1 голос
/ 15 апреля 2020

Во-первых, я бы порекомендовал вам использовать мюнхенскую группировку для получения различных значений вместо неэффективного метода, который вы используете сейчас.

Чтобы выполнить отдельную группировку для каждого row, включите уникальный идентификатор row' в ключе группировки:

XSLT 1.0

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

<xsl:key name="vehicle" match="Vehicle" use="concat(ManufacturerName, '|', generate-id(ancestor::row))" />

<xsl:template match="/Root">
    <xsl:for-each select="row">
        <xsl:variable name="row-id" select="generate-id()" />
        <!-- unique vahicles in this row -->
        <xsl:for-each select="data/a/b/c/Vehicle[count(. | key('vehicle', concat(ManufacturerName, '|', $row-id))[1]) = 1]">
            <xsl:value-of select="ManufacturerName"/>
            <xsl:text>, </xsl:text>
        </xsl:for-each>
        <xsl:text>&#xA;</xsl:text>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

Обратите внимание, что некоторые процессоры XSLT 1.0 поддерживают EXSLT set: different () функция расширения, которая значительно упрощает подобные вещи.

...