XPath рекурсивный "родительский" выбор в плоской структуре - PullRequest
0 голосов
/ 25 сентября 2019

Дан следующий XML:

<root>
  <element>
    <id>1</id>
  </element>
  <element>
    <id>2</id>
    <parentId>1</parentId>
  </element>
  <element>
    <id>3</id>
    <parentId>2</parentId>
  </element>
  <element>
    <id>4</id>
    <parentId>3</parentId>
  </element>
  <element>
    <id>5</id>
    <parentId>2</parentId>
  </element>
  <element>
    <id>6</id>
    <parentId>5</parentId>
  </element>
</root>

Теперь я хочу выбрать все «родительские» узлы, например, для элемента 3. Скажем, желаемый результат для элемента 3 должен быть:

  • элемент 1
  • элемент 2

Желаемый результат для элемента 2 должен быть:

  • элемент 1

И желаемый вывод для элемента 6 должен быть

  • , элемент 5
  • , элемент 2
  • , элемент 1

Isэтого вообще можно добиться с помощью XPath?Если да, то как ты мог это сделать?

1 Ответ

1 голос
/ 25 сентября 2019

Рассмотрим следующий пример:

XSLT 1.0

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

<xsl:param name="start-id"/>

<xsl:key name="elem" match="element" use="id"/>

<xsl:template match="/root">
    <root>
        <xsl:apply-templates select="key('elem', $start-id)"/>
    </root>
</xsl:template>

<xsl:template match="element">
    <element id="{id}"/>
    <xsl:apply-templates select="key('elem', parentId)"/>
</xsl:template>

</xsl:stylesheet>

Применение этого к вашему XML-вводу со значением параметра start-id 6 будетпроизводить:

Результат

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <element id="6"/>
  <element id="5"/>
  <element id="2"/>
  <element id="1"/>
</root>

Чтобы исключить начальный узел и перечислить только его предков, вы можете сделать:

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

<xsl:param name="start-id" select="6"/>

<xsl:key name="elem" match="element" use="id"/>

<xsl:template match="/root">
    <root>
        <xsl:apply-templates select="key('elem', key('elem', $start-id)/parentId)"/>
    </root>
</xsl:template>

<xsl:template match="element">
    <element id="{id}"/>
    <xsl:apply-templates select="key('elem', parentId)"/>
</xsl:template>

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