如何使用XSLT将XML节点及其子节点分组添加到新父节点?

时间:2015-11-02 18:32:25

标签: xml xslt xpath rename

我的示例XML如下所示:

<?xml version="1.0"?>
<Institutions>
    <Schools>
        <Name>Fictive High School 1</Name>
        <Teachers>
            <FirstName>John</FirstName>
            <LastName>Doe</LastName>
        </Teachers>
    </Schools>
    <Schools>
        <Name>Fictive High School 2</Name>
        <Teachers>
            <FirstName>Jack</FirstName>
            <LastName>Brown</LastName>
        </Teachers>
        <Teachers>
            <FirstName>Peter</FirstName>
            <LastName>Griffin</LastName>
        </Teachers>
    </Schools>
</Institutions>

目的是重命名“教师”中的“教师”,并将重命名的节点添加到新的父节点“教师”。 “学校”节点也应该这样做。所以这就是结果XML的样子:

<?xml version="1.0"?>
<Institutions>
    <Schools>
        <School>
            <Name>Fictive High School 1</Name>
            <Teachers>
                <Teacher>
                    <FirstName>John</FirstName>
                    <LastName>Doe</LastName>
                </Teacher>
            </Teachers>
        </School>
        <School>
            <Name>Fictive High School 2</Name>
            <Teachers>
                <Teacher>
                    <FirstName>Jack</FirstName>
                    <LastName>Brown</LastName>
                </Teacher>
                <Teacher>
                    <FirstName>Peter</FirstName>
                    <LastName>Griffin</LastName>
                </Teacher>
            </Teachers>
        </School>
    </Schools>
</Institutions>

现在我编写了以下XSLT以执行转换:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <!-- copy everything -->
    <xsl:template match="node()">
        <xsl:copy>
            <xsl:apply-templates select="node()"/>
        </xsl:copy>
    </xsl:template>

    <!-- rename Schools to School -->
    <xsl:template match="Schools">
        <School>
            <xsl:apply-templates select="node()"/>
        </School>
    </xsl:template>

    <!-- rename Teachers to Teacher -->
    <xsl:template match="Teachers">
        <Teacher>
            <xsl:apply-templates select="node()"/>
        </Teacher>
    </xsl:template>

    <!-- Add each School node to new node Schools -->
        <xsl:template match="/Institutions">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()[not(name() = 'Schools')]"/>
            <Schools>
                <xsl:apply-templates select="Schools"/>
            </Schools>
        </xsl:copy>
    </xsl:template>

    <!-- Add each Teacher node to new node Teachers -->
        <xsl:template match="/Institutions/School">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()[not(name() = 'Teachers')]"/>
            <Teachers>
                <xsl:apply-templates select="Teachers"/>
            </Teachers>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

不幸的是,最后一个块不起作用,我尝试了不同的方法。我是否必须使用学校而不是学校? XSLT处理器如何工作?

1 个答案:

答案 0 :(得分:0)

您只需覆盖Institutions(以创建新的Schools结构),Schools(以创建新的Teachers结构并重命名SchoolsSchool)和Teachers(重命名为Teacher)......

XML输入

<Institutions>
    <Schools>
        <Name>Fictive High School 1</Name>
        <Teachers>
            <FirstName>John</FirstName>
            <LastName>Doe</LastName>
        </Teachers>
    </Schools>
    <Schools>
        <Name>Fictive High School 2</Name>
        <Teachers>
            <FirstName>Jack</FirstName>
            <LastName>Brown</LastName>
        </Teachers>
        <Teachers>
            <FirstName>Peter</FirstName>
            <LastName>Griffin</LastName>
        </Teachers>
    </Schools>
</Institutions>

XSLT 2.0

<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="Institutions">
    <xsl:copy>
      <xsl:apply-templates select="@*|node() except Schools"/>
      <Schools>
        <xsl:apply-templates select="Schools"/>
      </Schools>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="Schools">
      <School>
        <xsl:apply-templates select="@*|node() except Teachers"/>
        <Teachers>
          <xsl:apply-templates select="Teachers"/>
        </Teachers>
      </School>
  </xsl:template>

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

</xsl:stylesheet>

XML输出

<Institutions>
   <Schools>
      <School>
         <Name>Fictive High School 1</Name>
         <Teachers>
            <Teacher>
               <FirstName>John</FirstName>
               <LastName>Doe</LastName>
            </Teacher>
         </Teachers>
      </School>
      <School>
         <Name>Fictive High School 2</Name>
         <Teachers>
            <Teacher>
               <FirstName>Jack</FirstName>
               <LastName>Brown</LastName>
            </Teacher>
            <Teacher>
               <FirstName>Peter</FirstName>
               <LastName>Griffin</LastName>
            </Teacher>
         </Teachers>
      </School>
   </Schools>
</Institutions>