Как извлечь все варианты реляционного XML для индекса - PullRequest
0 голосов
/ 15 ноября 2018

Я настроил индекс с местами.Результат должен быть от большего к меньшему, то есть

Нью-Йорк, Манхэттен, Уолл-стрит

Проблема в том, что иногда улицы не принадлежатодин район, но два, а иногда и вовсе нет района, но улицы перечислены непосредственно под городом.

Поэтому всякий раз, когда я получаю идентификатор и использую его в коде, подобном следующему:

<?xml version="1.0" encoding="UTF-8"?>
<listplaces>
    <place>
       <placeName type="city">City A</placeName>
        <idno>CA</idno>
    </place>
    <place>
        <placeName type="district">District B</placeName>
        <idno>DB</idno>
        <belongsTo active="CA" passive="DB"/>
    </place>
    <place>
        <placeName type="district">District C</placeName>
        <idno>DC</idno>
        <belongsTo active="CA" passive="DC"/>
    </place>
    <place>
        <placeName type="street">Street D</placeName>
        <idno>SD</idno>
        <belongsTo active="DB" passive="SD"/>
        <belongsTo active="DC" passive="SD"/>
    </place>
    <place>
        <placeName type="street">Street E</placeName>
        <idno>SE</idno>
        <belongsTo active="CA" passive="SE"/>
    </place>
</listplaces>

Это должно вывести в соответствии с idno

idno CA: City A
idno DB: City A, District B
idno DC: City A, District C
idno SD: City A, District B, Street D
idno SD: City A, District C, Street D
idno SE: City A, Street E

Проблема в том, что когда я на самом низком уровне, создать выход в правильном порядке - следовать всем @active отношениям наверх,Я нашел решение, в котором я записываю активное placeName всегда слева от строки.Но я понятия не имею, как заставить XSLT иметь дело со всеми возможными вариантами и создать соответственно столько строк, сколько необходимо.

(я использую XSLT 3.0)

Ответы [ 2 ]

0 голосов
/ 15 ноября 2018

Вот решение, использующее XSLT 1.0 :

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:strip-space elements="*"/>

<xsl:key name="parent" match="place" use="idno" />

<xsl:template match="place">
    <xsl:choose>
        <xsl:when test="not(belongsTo)">
            <xsl:text>idno </xsl:text>
            <xsl:value-of select="idno" />
            <xsl:text>: </xsl:text>
            <xsl:value-of select="placeName" />
            <xsl:text>&#10;</xsl:text>
        </xsl:when>
        <xsl:otherwise>
            <xsl:apply-templates select="belongsTo"/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

<xsl:template match="belongsTo">
    <xsl:text>idno </xsl:text>
    <xsl:value-of select="../idno" />
    <xsl:text>: </xsl:text>
    <xsl:apply-templates select="key('parent', @active)" mode="path"/>
    <xsl:value-of select="../placeName" />
    <xsl:text>&#10;</xsl:text>
</xsl:template>

<xsl:template match="place" mode="path">
    <xsl:apply-templates select="key('parent', belongsTo/@active)" mode="path"/>
    <xsl:value-of select="placeName" />
    <xsl:text>, </xsl:text>
</xsl:template>

</xsl:stylesheet>

Результат

idno CA: City A
idno DB: City A, District B
idno DC: City A, District C
idno SD: City A, District B, Street D
idno SD: City A, District C, Street D
idno SE: City A, Street E

Демо : http://xsltransform.hikmatu.com/eiZQaEN/1

0 голосов
/ 15 ноября 2018

Возможно, я неправильно понял логику, но рассмотрите возможность использования ключа для поиска мест на belongTo

<xsl:key name="places" match="place" use="belongsTo/@active" />

Вы начнете с выбора первого места (где $idno - это параметр, содержащий желаемое значение)

<xsl:apply-templates select="place[idno = $idno]" />

И затем в шаблоне, совпадающем с place, а также выводящем его, вы обрабатываете его "потомки", например,

<xsl:apply-templates select="key('places', idno)">

Это также передало бы параметр «пути» в это текущее место.

Попробуйте это XSLT

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

  <xsl:key name="places" match="place" use="belongsTo/@active" />

  <xsl:param name="idno" select="'CA'" />

  <xsl:template match="/*">
    <xsl:apply-templates select="place[idno = $idno]" />
  </xsl:template>

  <xsl:template match="place">
    <xsl:param name="previous" />
    <xsl:variable name="new" select="$previous[normalize-space()], placeName" />
    <xsl:text>idno {idno}: </xsl:text>
    <xsl:value-of select="$new" separator=", " />
    <xsl:text>&#10;</xsl:text>
    <xsl:apply-templates select="key('places', idno)">
      <xsl:with-param name="previous" select="$new" />
    </xsl:apply-templates>
  </xsl:template>
</xsl:stylesheet>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...