Соответствие переменной xslt в XML - PullRequest
0 голосов
/ 08 апреля 2011

Я пытаюсь выяснить, как использовать несколько шаблонов на основе атрибутов на более низких уровнях документа XML. Пример:

<World>
<Country value="USA">
    <State value="KY">
        <City value="Hebron"/>
        <City value="Lexington"/>
        <City value="Owensboro"/>
        <City value="Jonesville"/>
    </State>
    <State value="OH">
        <City value="Cincinnati"/>
        <City value="Columbus"/>
        <City value="Cleveland"/>
        <City value="Jonesville"/>
    </State>
    <State value="IN">
        <City value="Indianapolis"/>
    </State>
</Country>
</World>
<World>
<Country value="Russia">
  <State value="Estonia">
        <City value="Tallinn"/>
        <City value="Dorpat"/>
        <City value="Owensboro"/>
  </State>
  <State value="Ukraine">
        <City value="Kiev"/>
        <City value="Sevastopol"/>
        <City value="Slavutych"/>
        <City value="Jonesville"/>
  </State>
</Country>
</World>

Я собираюсь получить экземпляры документов XML, поскольку это будет либо Страна = США, либо Россия, но я не буду знать, какие именно. Я хочу применить один XSLT, который позволит использовать любую страну и в результате скопировать разные города.

если в США, например, вывод будет выглядеть так:

<World>
<Country value="USA">
 <State value="KY">
     <City value="Hebron" />
 </State>
 <State value="OH">
      <City value="Cincinnati" />
      <City value="Jonesville" />
 </State>
 </Country>
</World> 

если это Россия:

<World>
<Country value="Russia">
 <State value="Estonia">
     <City value="Dorpat" />
     <City value="Owensboro" />
 </State>
 <State value="Ukraine">
      <City value="Keiv" />
      <City value="Sevastopol" />
      <City value="Slavutych" />
 </State>
 </Country>
</World> 

Также обратите внимание, что можно хотеть город в одном штате, но не в другом (т.е. ОН против КИ, Джонсвилль).

Я могу заставить работать одну страну, но я не понимаю, как заставить шаблоны соответствовать различным атрибутам. Есть идеи?

Ответы [ 2 ]

0 голосов
/ 09 апреля 2011

Следующая таблица стилей выполняет некоторую базовую проверку / фильтрацию:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                              xmlns:my="my">
    <my:vals>
        <v v="USA|KY|Hebron" />
        <v v="USA|OH|Cincinnati" />
        <v v="USA|OH|Jonesville" />
        <v v="Russia|Estonia|Dorpat" />
        <v v="Russia|Estonia|Owensboro" />
        <v v="Russia|Ukraine|Kiev" />
        <v v="Russia|Ukraine|Sevastopol" />
        <v v="Russia|Ukraine|Slavutych" />
    </my:vals>
    <xsl:variable name="vals" select="document('')/*/my:vals/*" />
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template>
    <xsl:template match="World">
        <xsl:copy>
            <xsl:apply-templates
                select="@*|Country[State/City[
                   concat(../../@value, '|', ../@value, '|', @value)=$vals/@v]]" />
        </xsl:copy>
    </xsl:template>
    <xsl:template match="Country">
        <xsl:copy>
            <xsl:apply-templates
                select="@*|State[City[
                   concat(../../@value, '|', ../@value, '|', @value)=$vals/@v]]" />
        </xsl:copy>
    </xsl:template>
    <xsl:template match="State">
        <xsl:copy>
            <xsl:apply-templates
                select="@*|City[
                    concat(../../@value, '|', ../@value, '|', @value)=$vals/@v]" />
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

На этом входе:

<World>
    <Country value="USA">
        <State value="KY">
            <City value="Hebron" />
            <City value="Lexington" />
            <City value="Owensboro" />
            <City value="Jonesville" />
        </State>
        <State value="OH">
            <City value="Cincinnati" />
            <City value="Columbus" />
            <City value="Cleveland" />
            <City value="Jonesville" />
        </State>
        <State value="IN">
            <City value="Indianapolis" />
        </State>
    </Country>
    <Country value="Russia">
        <State value="Estonia">
            <City value="Tallinn" />
            <City value="Dorpat" />
            <City value="Owensboro" />
        </State>
        <State value="Ukraine">
            <City value="Kiev" />
            <City value="Sevastopol" />
            <City value="Slavutych" />
            <City value="Jonesville" />
        </State>
    </Country>
</World>

Производит:

<World>
    <Country value="USA">
        <State value="KY">
            <City value="Hebron" />
        </State>
        <State value="OH">
            <City value="Cincinnati" />
            <City value="Jonesville" />
        </State>
    </Country>
    <Country value="Russia">
        <State value="Estonia">
            <City value="Dorpat" />
            <City value="Owensboro" />
        </State>
        <State value="Ukraine">
            <City value="Kiev" />
            <City value="Sevastopol" />
            <City value="Slavutych" />
        </State>
    </Country>
</World>

Объяснение: Мы вводим только Country элементы, которые содержат допустимые комбинации State и City;только State элементы, которые содержат действительный City;и только действительные элементы City.Все недействительные или пустые элементы удаляются.

0 голосов
/ 08 апреля 2011

Исходя из вашего комментария о том, что ваш пользователь будет указывать нужные города с помощью каких-то параметрических критериев, я думаю, вы бы сделали что-то вроде следующего (обратите внимание на псевдокод "SATISFIES CRITERIA", так как я не знаю точно, какие критерии город @value должен удовлетворить):

<stylesheet xmlns="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <template match="/World">
      <copy>
         <apply-templates select="Country[ State/City[ @value SATISFIES CRITERIA ] ]" />
      </copy>
   </template>

   <template match="Country|State|@*">
      <copy>
         <apply-templates select="*|@*" />
      </copy>
   </template>

   <template match="City[ @value SATISFIES CRITERIA ]">
      <copy>
         <apply-templates select="@*" />
      </copy>
   </template>
</stylesheet>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...