如何将子元素包装在父标签中?

How to wrap child elements in a parent tag?

我想在选项卡中包装标签元素,在面板中包装面板元素

这是我的输入:

<test>
  <gui>
    <c name="NAME">dock1</c>
    <tab>
      <c name="NAME">TAB1</c>
      <panel>
        <c name="NAME">TAB1_1</c>
      </panel>
      <panel>
        <c name="NAME">TAB1_2</c>
      </panel>
    </tab>
  </gui>
  <gui>
    <c name="NAME">dock2</c>
    <tab>
      <c name="NAME">TAB2</c>
      <panel>
        <c name="NAME">TAB2_1</c>
      </panel>
    </tab>
    <tab>
      <c name="NAME">TAB2</c>
      <panel>
        <c name="NAME">TAB2_1</c>
      </panel>
    </tab>
    <tab>
      <c name="NAME">TAB3</c>
      <panel>
        <c name="NAME">TAB3_1</c>
        <c name="MODEL"/>
      </panel>
    </tab>
  </gui>
</test>

期望的输出:

<?xml version="1.0" encoding="UTF-8"?>
<test>
  <gui>
    <c name="NAME">dock1</c>
    <tabs>
      <tab>
        <c name="NAME">TAB1</c>
        <panels>
          <c name="NAME">TAB1</c>
          <panel>
            <c name="NAME">TAB1_1</c>
          </panel>
          <panel>
            <c name="NAME">TAB1_2</c>
          </panel>
        </panels>
      </tab>
    </tabs>
  </gui>
  <gui>
    <c name="NAME">dock2</c>
    <tabs>
      <tab>
        <c name="NAME">TAB2</c>
        <panels>
          <c name="NAME">TAB2</c>
          <panel>
            <c name="NAME">TAB2_1</c>
          </panel>
        </panels>
      </tab>
      <tab>
        <c name="NAME">TAB2</c>
        <panels>
          <c name="NAME">TAB2</c>
          <panel>
            <c name="NAME">TAB2_1</c>
          </panel>
        </panels>
      </tab>
      <tab>
        <c name="NAME">TAB3</c>
        <panels>
          <c name="NAME">TAB3</c>
          <panel>
            <c name="NAME">TAB3_1</c>
            <c name="MODEL"></c>
          </panel>
        </panels>
      </tab>
    </tabs>
  </gui>
</test>

这是我的 XSLT:

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

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

  <xsl:template match="/test/gui">
    <xsl:copy>
      <xsl:apply-templates select="c[@name='NAME']"/>
      <xsl:element name="tabs">
        <xsl:for-each select="tab">
          <xsl:copy>          
            <xsl:apply-templates select="c[@name='NAME']"/>
            <xsl:element name="panels">
              <xsl:apply-templates select="@*|node()"/>
            </xsl:element>
          </xsl:copy>
        </xsl:for-each>
      </xsl:element>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

有点效果,但是 spacing/new 行有问题

她的是我的输出:

<?xml version="1.0" encoding="UTF-8"?><test>
  <gui><c name="NAME">dock1</c>
<tabs><tab><c name="NAME">TAB1</c>
<panels>
      <c name="NAME">TAB1</c>
      <panel>
        <c name="NAME">TAB1_1</c>
      </panel>
      <panel>
        <c name="NAME">TAB1_2</c>
      </panel>
    </panels>
</tab>
</tabs>
</gui>
  <gui><c name="NAME">dock2</c>
<tabs><tab><c name="NAME">TAB2</c>
<panels>
      <c name="NAME">TAB2</c>
      <panel>
        <c name="NAME">TAB2_1</c>
      </panel>
    </panels>
</tab>
<tab><c name="NAME">TAB2</c>
<panels>
      <c name="NAME">TAB2</c>
      <panel>
        <c name="NAME">TAB2_1</c>
      </panel>
    </panels>
</tab>
<tab><c name="NAME">TAB3</c>
<panels>
      <c name="NAME">TAB3</c>
      <panel>
        <c name="NAME">TAB3_1</c>
        <c name="MODEL"/>
      </panel>
    </panels>
</tab>
</tabs>
</gui>
</test>

为什么我的输出是这样的,我该如何解决?

添加 <xsl:strip-space elements="*"/> 你应该得到缩进:http://xsltfiddle.liberty-development.net/eiQZDbn

如果您需要使用 Xalan,那么它有一个自定义属性 <xsl:output method="xml" version="1.0" indent="yes" xmlns:xalan="http://xml.apache.org/xslt" xalan:indent-amount="2"/> 您可以申请获得缩进:http://xsltransform.hikmatu.com/3Nqn5Yb