Выбор XPath для повторения структуры узла в XSLT 2.0 - PullRequest
0 голосов
/ 03 мая 2018

Я пытался решить эту проблему некоторое время.

XML Пример:

<node>
  <ID>123</ID>
  <work>
    <id>1</id>
    <title>Engineer</title>
    <description>
      <short>short</short>
    </description>
  </work>
  <work>
    <id>2</id>
    <title>Engineer</title>
    <description>
      <short>long</short>
    </description>
  </work>
</node>

XSLT 2.0 Пример:

<xsl:template name="answers">
    <xsl:for-each select="//description">
        <xsl:choose>
            <xsl:when test="ancestor::node[ID='123']/work[2]/description/short"> 
                //DO NOTHING.
            </xsl:when>
            <otherwise>
                 <description>
                  //CREATE OTHERS
                 </description>
            </otherwise>
        </xsl:choose>
    </xsl:for-each>
</xsl:template>

Идея в том, чтобы создать новый шаблон для части "для каждого описания". Но я хочу только первое описание, потому что я напишу второе внутри первого. Поэтому мне не нужно ничего создавать для второго описания. Просто игнорируйте, когда это второе описание, которое имеет <short> узел. Решение не может быть определено с использованием значения short='long'. Поскольку язык или значение могут измениться, но позиция XPath всегда будет одинаковой.

Результат, который я получаю, с этим

long
long

Поэтому, когда я выполняю код, он также игнорирует первый узел, потому что они принадлежат одному и тому же ID='123', я думаю. Эта группа с тем же ID может повторяться N раз. Как выбрать только второй work узел description, каждый повторяемый раз со значением "long" по XPath, не основанный на текстовом значении.

1 Ответ

0 голосов
/ 06 мая 2018

Как я понял, вы хотите обработать сначала description с каждого node с ребенком ID = 123.

Это приводит к выводу, что у вас есть несколько node элементов, поэтому из-за требований синтаксиса XML они должны быть потомками некоторых родителей узел (я предположил, что они прямые дети).

Чтобы получить необходимое значение, вы можете использовать:

<xsl:value-of select="descendant::description[1]/short"/>

, где descendant::description[1] дает только первый description элемент, независимо от его глубины в дереве XML.

Весь сценарий может быть таким, как показано ниже:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
  <xsl:output method="xml" encoding="UTF-8" indent="yes" />

  <xsl:template match="root">
    <xsl:copy>
      <xsl:for-each select="node[ID='123']">
        <description>
          <xsl:value-of select="descendant::description[1]/short"/>  
        </description>
      </xsl:for-each>
    </xsl:copy>
  </xsl:template>
</xsl:transform>

Рабочий пример см. http://xsltransform.net/pNvs5wi

Я "расширил" ваш источник XML, так что он содержит 2 node элементов и мой скрипт выводит первые описания из каждого источника node.

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