Как написать лучший XSLT при работе с потенциальным циклом в ситуации цикла? - PullRequest
0 голосов
/ 03 марта 2012

У меня есть такой XML-код:

<?xml version="1.0" encoding="UTF-8"?>
<row>
    <cell colname="1"><Name>SomeValue<Ref format="Ref" Idref="ABC"/></Name></cell>
    <cell colname="2"><Selection>
        <Config><Configuration>AAA</Configuration></Config>
        <Config><Configuration>BBB</Configuration></Config>
    </Selection></cell>
    <cell colname="6"><Notes>
        <Text><IteratorDef>
            <IteratorTag Id="ABC">DDi</IteratorTag>
            <IteratorList>
                <IteratorChoice>05</IteratorChoice>
                <IteratorChoice>10</IteratorChoice>
                <IteratorChoice>15</IteratorChoice>
            </IteratorList>
        </IteratorDef></Text>
    </Notes></cell>
</row>

Я бы хотел получить такой результат:

Ссылка указывает на IteratorTag: есть две конфигурации, а именно AAA иВ.Для каждой конфигурации есть несколько значений IteratorChoice.Каждое необходимо объединить со значением Имя + значение IteratorTag, поэтому SomeValue + DDi + 05, SomeValue + DDi + 10 и SomeValue + DDi + 15.

   AAA
   SomeValueDDi05
   SomeValueDDi10
   SomeValueDDi15

   BBB
   SomeValueDDi05
   SomeValueDDi10
   SomeValueDDi15

Моя мысль - написать цикл в цикле с ключами for-each для тегов IteratorList и Configuration (цикл Configuration будет внутри цикла IteratorList), это правильный подход с использованием XSLT?

TIA,

Джон

1 Ответ

2 голосов
/ 04 марта 2012

решение1: работает только при условии ввода.
Вот код:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" indent="yes"/>
  <xsl:variable name="newline" select="'&#13;'"/>

  <xsl:template match="row/cell/Selection/Config/Configuration">
    <xsl:value-of select="concat(.,$newline)"/><!--AAA, BBB, etc-->

    <xsl:for-each select="/row/cell/Notes/Text/IteratorDef/IteratorList/IteratorChoice">
      <xsl:variable name="zstring" select="."/>
      <xsl:for-each select="ancestor::IteratorDef/IteratorTag">
        <xsl:variable name="ystring" select="concat(.,$zstring)"/>
        <xsl:for-each select="ancestor::row/cell/Name">
          <xsl:value-of select="concat(normalize-space(.),$ystring,$newline)"/>
        </xsl:for-each>
      </xsl:for-each>
    </xsl:for-each>

    <!--this is for extra line space after each CONFIGURATION block-->
    <xsl:value-of select="$newline"/>
  </xsl:template>
  <xsl:template match="text()"/>
</xsl:stylesheet>

Изменить: Решение 2 .. Я не использовал обратный XPath, но полный XPath .. это работает на надежном XML. метод немного отличается .. здесь я Я иду с высокого уровня (XPath) на более низкий уровень. Это код:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" indent="yes"/>
  <xsl:variable name="newline" select="'&#13;'"/>

  <xsl:template match="row/cell/Selection/Config/Configuration">
    <xsl:value-of select="concat(.,$newline)"/><!--AAA, BBB, etc-->

    <xsl:for-each select="/row/cell/Name">
      <xsl:variable name="astring" select="normalize-space(.)"/>
      <xsl:for-each select="/row/cell/Notes/Text/IteratorDef/IteratorTag">
        <xsl:variable name="bstring" select="concat($astring,normalize-space(.))"/>
        <xsl:for-each select="/row/cell/Notes/Text/IteratorDef/IteratorList/IteratorChoice">
          <xsl:value-of select="concat($bstring,normalize-space(.),$newline)"/>
        </xsl:for-each>
      </xsl:for-each>
    </xsl:for-each>

    <!--this is for extra line space after each CONFIGURATION block-->
    <xsl:value-of select="$newline"/>
  </xsl:template>

  <!--disable all unwanted text nodes-->
  <xsl:template match="text()"/>
</xsl:stylesheet>

Если это ваш XML:

<?xml version="1.0" encoding="UTF-8"?>
<row>
  <cell colname="1">
    <Name>
      SomeValue<Ref format="Ref" Idref="ABC"/>
    </Name>
  </cell>
  <cell colname="2">
    <Selection>
      <Config>
        <Configuration>AAA</Configuration>
      </Config>
      <Config>
        <Configuration>BBB</Configuration>
      </Config>
      <Config>
        <Configuration>CCC</Configuration>
      </Config>
    </Selection>
  </cell>
  <cell colname="6">
    <Notes>
      <Text>
        <IteratorDef>
          <IteratorTag Id="ABC">DDi</IteratorTag>
          <IteratorTag Id="ABC">EEi</IteratorTag>
          <IteratorList>
            <IteratorChoice>05</IteratorChoice>
            <IteratorChoice>10</IteratorChoice>
            <IteratorChoice>15</IteratorChoice>
            <IteratorChoice>20</IteratorChoice>
          </IteratorList>
        </IteratorDef>
      </Text>
    </Notes>
  </cell>
</row>

Это будет ваш вывод:

AAA
SomeValueDDi05
SomeValueDDi10
SomeValueDDi15
SomeValueDDi20
SomeValueEEi05
SomeValueEEi10
SomeValueEEi15
SomeValueEEi20

BBB
SomeValueDDi05
SomeValueDDi10
SomeValueDDi15
SomeValueDDi20
SomeValueEEi05
SomeValueEEi10
SomeValueEEi15
SomeValueEEi20

CCC
SomeValueDDi05
SomeValueDDi10
SomeValueDDi15
SomeValueDDi20
SomeValueEEi05
SomeValueEEi10
SomeValueEEi15
SomeValueEEi20
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...