Добавление родительского тега к существующим элементам? - PullRequest
3 голосов
/ 09 сентября 2011

Есть ли способ добавить родительский тег в существующий набор узлов?

Пример:

<root>
<c>
  <d></d>
<e>
  <f></f>
</e>
<b></b>
<b></b>
<b></b>
</c>
</root>

Желаемый вывод:

   <root>
   <c>
      <d></d>
    <e>
      <f></f>
    </e>
    <a>
    <b></b>
    <b></b>
    <b></b>
    </a>
</c>
    </root>

Спасибо!

Ответы [ 3 ]

3 голосов
/ 09 сентября 2011

@ empo ответ работает только в очень простых случаях, а не с таким XML-документом, как этот :

<root>
    <c>
        <d></d>
        <e>
            <f></f>
        </e>
        <b></b>
        <b></b>
        <b></b>
    </c>
    <b></b>
    <b></b>
</root>

Здесь, если мы хотим обернуть каждую группу последовательных b с в a, один из способов добиться этого - :

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>
 <xsl:key name="kFollowing" match="b"
  use="generate-id(preceding-sibling::*[not(self::b)][1])"/>

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

 <xsl:template match="b[not(preceding-sibling::*[1][self::b])]">
  <a>
   <xsl:copy-of select=
   "key('kFollowing', generate-id(preceding-sibling::*[1]))"/>
  </a>
 </xsl:template>
 <xsl:template match="b"/>
</xsl:stylesheet>

когда это преобразование применяется к вышеуказанному XML-документу, требуемый правильный результат (все группы последовательных b s заключены в a), получается :

<root>
   <c>
      <d/>
      <e>
         <f/>
      </e>
      <a>
         <b/>
         <b/>
         <b/>
      </a>
   </c>
   <a>
      <b/>
      <b/>
   </a>
</root>
2 голосов
/ 09 сентября 2011

Надеюсь, ваш XML теперь намного лучше отражает ваш реальный случай, вы можете использовать:

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

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

    <xsl:template match="root/c/b[1]">
        <a>
            <xsl:copy-of select="self::*|following::b"/>
        </a>
    </xsl:template>

    <xsl:template match="b"/>

</xsl:stylesheet>
1 голос
/ 09 сентября 2011

Вы можете использовать преобразование личности и сделать это:

  <xsl:template match="root">
    <root>
      <a>
        <xsl:apply-templates/>
      </a>
    </root>
  </xsl:template>

  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...