Как вернуться назад в гнездо тегов в xml - PullRequest
1 голос
/ 28 августа 2009

Лучший способ объяснить мою проблему - привести пример xml:

<block>
  <if>
    <trans>
      <trans1>
        <text1>text</text1>
      </trans1>
      <trans1>
        <text1>text</text1>
      </trans1>
    </trans>
    <if>
      <trans>
        .......
      </trans>
    </if>
  </if>
</block>

Таким образом, чтобы захватить все данные в нем, вы должны сделать (xsl: for-each select = "block / if / trans / trans1") ... получить данные. Теперь я хочу выйти из trans и trans1, чтобы перейти в "block / if / if" ...

Я знаю, что мог бы сделать отдельные для каждого, но мне нужно собрать все эти данные в одной ячейке таблицы, поэтому вам нужно будет сделать вложенные для каждого, но я не знаю, можете ли вы можно немного вернуться назад?

Кто-нибудь знает, возможно ли это, и если да, то как это сделать?

Ответы [ 2 ]

1 голос
/ 30 августа 2009

Таким образом, чтобы захватить все данные в нем, вы должны сделать (xsl: for-each select = "block / if / trans / trans1")

Нет, я бы не стал. Я почти никогда не использую для каждого. Я бы сделал:

<xsl:apply-templates select="block/if/trans/trans1"/>

Теперь я хочу выйти из trans и trans1, чтобы я мог перейти в «block / if / if» ..

Если trans1 является узлом контекста, вы можете использовать ось предка, чтобы добраться до своего первого if предка:

<xsl:template match="trans1">
   <xsl:apply-templates select="ancestor::if[1]"/>
</xsl:template>

Правда, не совсем понятно, о чем вы спрашиваете. Вы пытаетесь сгладить иерархию и создать таблицу HTML из каждой block, которая имеет tr для каждого if и td для каждого text1 элемента под каждым if? Если это так, для этого потребуется что-то вроде этого:

<xsl:template match="block">
   <table>
      <xsl:apply-templates select=".//if"/>
   </table>
</xsl:template>

<xsl:template match="if">
   <tr>
      <xsl:apply-templates select="trans/trans1/text1"/>
   </tr>
</xsl:template>

<xsl:template match="text1">
   <td>
      <xsl:value-of select="."/>
   </td>
</xsl:template>

В приведенном выше примере я предположил, что вы знаете точный путь к потомку text1, как показано в вашем примере.

Если вы не знаете точный путь от элемента if к потомкам text1, это сложнее. Вы не хотите использовать

.//text1

, потому что это выберет всех text1 потомков, включая тех, которые являются потомками if элементов-потомков. Это приведет к тому, что один и тот же элемент text1 создаст несколько td элементов на выходе - по одному на каждый элемент if, потомком которого он является. Чтобы избежать этого, вам нужно использовать шаблон вроде:

text1 | .//*[name() != 'if']//text1

Это выбирает любых непосредственных text1 потомков, а также любых text1 потомков, которые сами не являются потомками потомков if элементов.

На самом деле, это также будет работать:

. // text1 [ancestor :: if [1] = current ()]

Это находит всех text1 потомков, чей первый предок if, двигаясь вверх по цепочке предков, является текущим if элементом. Это легче понять, чем в первом примере, но первый пример, вероятно, работает лучше, если процессор XSLT не очень умный.

0 голосов
/ 28 августа 2009

Не совсем понятно, что вам нужно делать. Вот мое предположение, что вы хотите извлечь из /block/if всех trans/trans1 элементов независимо от того, под каким if они находятся. На этом основании попробуйте: -

 <xsl:for-each select="block/if//trans/trans1">

Обратите внимание, что // в пути является сокращением для descendants:: и выберет любое вхождение trans на любой глубине ниже родительского if.

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