Оберните некоторые узлы с помощью XSL - PullRequest
0 голосов
/ 28 сентября 2010

Я хочу обернуть дочерние узлы <foo/>, которые не <bar/> или <baz/>, в <corge/>.

Примечание: <bar/> и <baz/> всегда будут первыми дочерними узлами <foo/>

Преобразование этого:

<root>
    <foo>
       <bar>bar</bar>
       <baz>baz</baz>
       <qux>qux</qux>
       <grault>grault</grault>
    </foo>
     <foo>
       <bar>bar</bar>
       <baz>baz</baz>
       <qux>qux</qux>
       <quux>quux</quux>
    </foo>
</root>

к этому:

<root>
    <foo>
       <bar>bar</bar>
       <baz>baz</baz>
       <corge>
           <qux>qux</qux>
           <grault>grault</grault>
       </corge>
    </foo>
    <foo>
       <bar>bar</bar>
       <baz>baz</baz>
       <corge>
           <qux>qux</qux>
           <quux>quux</quux>
       </corge>
    </foo>
</root>

Какой хороший способ сделать это с помощью XSL?

Ответы [ 2 ]

1 голос
/ 28 сентября 2010

Эта таблица стилей:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="node()|@*" name="identity">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="foo/*"/>
    <xsl:template match="foo/bar|foo/baz">
        <xsl:call-template name="identity"/>
    </xsl:template>
    <xsl:template match="foo/*[not(self::bar or self::baz)][1]">
        <corge>
            <xsl:apply-templates select="../*[not(self::bar or self::baz)]"
                                 mode="corge"/>
        </corge>
    </xsl:template>
    <xsl:template match="foo/*" mode="corge">
        <xsl:call-template name="identity"/>
    </xsl:template>
</xsl:stylesheet>

Выход:

<root>
    <foo>
        <bar>bar</bar>
        <baz>baz</baz>
        <corge>
            <qux>qux</qux>
            <grault>grault</grault>
        </corge>
    </foo>
    <foo>
        <bar>bar</bar>
        <baz>baz</baz>
        <corge>
            <qux>qux</qux>
            <quux>quux</quux>
        </corge>
    </foo>
</root>

Примечание : стиль вывода и режимы для применения шаблонов. Если элемент для переноса отсутствует, элемент corge не будет выводиться.

Другая таблица стилей (компактный код, менее многократно используемый):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="root">
        <root>
            <xsl:apply-templates/>
        </root>
    </xsl:template>
    <xsl:template match="foo">
        <foo>
            <xsl:copy-of select="bar|baz"/>
            <corge>
                <xsl:copy-of select="*[not(self::bar or self::baz)]"/>
            </corge>
        </foo>
    </xsl:template>
</xsl:stylesheet>
0 голосов
/ 28 сентября 2010

Вот как бы я это сделал ...

XML

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <foo>
    <bar>bar</bar>
    <baz>baz</baz>
    <qux>qux</qux>
    <grault>grault</grault>
  </foo>
  <foo>
    <bar>bar</bar>
    <baz>baz</baz>
    <qux>qux</qux>
    <quux>quux</quux>
  </foo>
</root>

XSL

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>
  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>
  <xsl:template match="foo">
    <foo>
      <xsl:apply-templates select="bar|baz"/>
      <corge>
        <xsl:apply-templates select="*[name() != 'bar' and name() != 'baz']"/>
      </corge>
    </foo>
  </xsl:template>
</xsl:stylesheet>

ВЫХОД

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <foo>
      <bar>bar</bar>
      <baz>baz</baz>
      <corge>
         <qux>qux</qux>
         <grault>grault</grault>
      </corge>
   </foo>
   <foo>
      <bar>bar</bar>
      <baz>baz</baz>
      <corge>
         <qux>qux</qux>
         <quux>quux</quux>
      </corge>
   </foo>
</root>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...