XSLT-обработка, когда важен заказ - PullRequest
1 голос
/ 17 марта 2009

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

В основном это так. У меня есть документ XML, который выглядит так ...

<tag1>
  <tag2>
    foo
  </tag2>
  <tag3>
    bar
   </tag3>

  <tag2>
    goo
  </tag2>
  <tag3>
    mar
  </tag3>
</tag1>

Итак, подвох в том, что порядок важен. Элементы в tag2 и tag3 объединяются в группы. То есть «foo» и «bar» должны обрабатываться вместе, также как и «goo» и «mar».

Я не знаю, как уловить это в конструкции. То есть я могу сопоставить tag2 и tag3, но я не знаю, как привести их в порядок, вместе.

Есть идеи?

Ответы [ 5 ]

4 голосов
/ 17 марта 2009

Вот простой способ сделать группировку, если ваши исходные данные уже упорядочены так, как вы ожидаете:

<xsl:apply-templates select="/tag1/*[position() mod 2 = 1]" mode="group"/>

Это будет применять шаблоны к каждому нечетному дочернему элементу tag1 независимо от имени. Вы используете режим для ограничения применяемого шаблона (потому что этот шаблон должен соответствовать *). Внутри шаблона вы можете использовать ось поиска following-sibling, чтобы получить следующий узел. Это дает вам что-то вроде:

<xsl:template match="*" mode="group">
   <xsl:variable name="next" select="following-sibling::*[1]"/>
   <group>
      <xsl:copy-of select="."/>
      <xsl:copy-of select="$next"/>
   </group>
</xsl:template>

Еще проще, если вы можете полагаться на имена элементов:

<xsl:apply-templates select="/tag1/tag2"/>

<xsl:template match="tag2">
   <xsl:variable name="next" select="following-sibling::tag3[1]"/>
   <group>
      <xsl:copy-of select="."/>
      <xsl:copy-of select="$next"/>
   </group>
</xsl:template>

Обратите внимание: если вы группируете все N элементов, вы можете получить список текущего элемента и его следующих N-1 братьев и сестер:

<xsl:variable name="list" select=". | following-sibling::*[position() &lt; $n]"/>
2 голосов
/ 17 марта 2009

Кайл, похоже, на правильном пути:

в частности, если вы просто хотите получить каждую пару значений tag2 и tag3 и предполагать, что эти значения всегда отображаются в порядке в узле tag1, я бы использовал XSL, например (очень упрощенно):

<xsl:template match="//tag1">
  <xsl:for-each select="tag2">
    <xsl:value-of select="self::node()" />
    <xsl:value-of select="following-sibling::tag3[1]" />
  </xsl:for-each>
</xsl:template>
0 голосов
/ 17 марта 2009

Вот преобразование XSLT 1.0, которое группирует двух последовательных дочерних элементов <tag1> на основе их положения в документе.

<xsl:stylesheet version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:template match="tag1">
    <root>
      <xsl:apply-templates select="*[position() mod 2 = 1]" />
    </root>
  </xsl:template>

  <xsl:template match="tag1/*">
    <xsl:variable name="next" select="following-sibling::*[1]" />   
    <together>
      <xsl:value-of select="normalize-space(concat(., $next))" />
    </together>
  </xsl:template>
</xsl:stylesheet>

Вот как это работает:

  • начиная с <tag1>, он выводит корневой узел <root>, а затем выбирает тех потомков <tag1>, которые находятся в начале группы (position() mod 2 = 1) для дальнейшей обработки
  • для каждого из этих узлов второй шаблон выводит текстовое содержимое выбранного узла, и он следует за родным братом

Мой тестовый вывод:

<root>
  <together>foo bar</together>
  <together>goo mar</together>
</root>
0 голосов
/ 17 марта 2009

Я подозреваю, что это невозможно при одном простом выборе. Кроме того, вы можете обрабатывать группы отдельно,

<xsl:apply-templates select="foo|bar"/>
<xsl:apply-templates select="goo|mar"/>

с использованием шаблона, который соответствует всем этим.

0 голосов
/ 17 марта 2009

Если вам просто нужно последовательно обработать все элементы «tag2» и «tag3», то вы можете просто указать «tag2 | tag3» в качестве запроса XPath при их выборе.

Если это действительно единица, которую нужно обработать, то "tag2" и "tag3" должны быть действительно сгруппированы вместе под новым родительским элементом.

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