Изменить положение узла с помощью XSLT - PullRequest
6 голосов
/ 27 апреля 2011

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

<root>
    <a>
        <b1>SampleB1</b1>
        <b2>
            <c1>zyx</c1>
            <c2>wvu</c2>
            <c3>tsr</c3>
            <c4>dtg</c4>
            <c5>hkj</c5>
        </b2>
        <b3>SampleB3</b3>
    </a>
</root>

Затем я хочу изменить положение узлов 'c4' и 'c5' и хочу выводить как:

<root>
    <c4>dtg</c4>
    <c5>hkj</c5>
    <a>
        <b1>SampleB1</b1>
        <b2>
            <c1>zyx</c1>
            <c2>wvu</c2>
            <c3>tsr</c3>
        </b2>
        <b3>SampleB3</b3>
    </a>
</root>

Может кто-нибудь сказать, пожалуйста, как мы можем это сделать.

Спасибо !!!

Ответы [ 3 ]

1 голос
/ 27 апреля 2011

Стиль чистого натяжения:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:strip-space elements="*"/>
    <xsl:template match="node()|@*" name="identity">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="a">
        <xsl:apply-templates mode="search"/>
        <xsl:call-template name="identity"/>
    </xsl:template>
    <xsl:template match="c4|c5"/>
    <xsl:template match="c4|c5" mode="search">
        <xsl:call-template name="identity"/>
    </xsl:template>
    <xsl:template match="text()" mode="search"/>
</xsl:stylesheet>

Выход:

<root>
    <c4>dtg</c4>
    <c5>hkj</c5>
    <a>
        <b1>SampleB1</b1>
        <b2>
            <c1>zyx</c1>
            <c2>wvu</c2>
            <c3>tsr</c3>
        </b2>
        <b3>SampleB3</b3>
    </a>
</root>
1 голос
/ 27 апреля 2011

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

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>

  <!-- By default, recursively copy all nodes unchanged -->
  <xsl:template match="@* | node()">
      <xsl:copy>
          <xsl:apply-templates select="@* | node()"/>
      </xsl:copy>
  </xsl:template>

  <!-- But don't copy root/a/b2/c3 and root/a/b2/c4 -->
  <xsl:template match="root/a/b2/c3" />
  <xsl:template match="root/a/b2/c4" />

  <xsl:template match="root">
    <xsl:copy>
      <!-- Place a copy of a/b2/c3 and a/b2/c4 at the start of root -->
      <xsl:copy-of select="a/b2/c3" />
      <xsl:copy-of select="a/b2/c4" />
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

Ключ к пониманию вышеизложенного состоит в том, что он не перемещает элементы, а копирует элементы, а затем пропускает их в другом месте,К сожалению, это означает, что нам нужно указать элементы для перемещения дважды (один раз, чтобы пропустить их, а затем еще раз, чтобы включить их копию в другом месте), но в настоящее время я не могу придумать более аккуратный способ.

Этот вопрос - Перемещение подузлов в родительские атрибуты с помощью XSLT также может быть полезным.

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

Чтобы изменить порядок, вам нужно настроить XSL так, чтобы он копировал то, что вам нужно, в том порядке и в том месте, где вы хотите. Например:

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

    <!-- At the root element, recurse through any descendant c4 or c5 nodes first -->
    <xsl:template match="root">
        <xsl:copy>
            <xsl:apply-templates select="//c4|//c5"/>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>

    <!-- At the b2 element, copy everything but the C4 or C5 nodes -->
    <xsl:template match="b2">
        <xsl:copy>
            <xsl:apply-templates select="node()[not(self::c4|self::c5)]|@*"/>
        </xsl:copy>
    </xsl:template>

    <!-- Identity -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

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