使用XSLT将XML重组为另一个XML

时间:2016-09-06 12:44:07

标签: xml xslt

我需要将给出每个学生数据的Students.xml转换为Courses.xml,其中每个课程组织这些数据。 当我每个学生有一门课程时,我能够实现这一点,但是如果每个学生提供的课程超过一门,结果都是错误的。有没有办法让我可以在数组中获取所有课程名称,然后根据我的xsl文件中的这些值进行循环?

Students.xml

<?xml version="1.0" encoding="UTF-8"?>
<Students>
  <Student>
    <name>A</name>
    <rollNo>1</rollNo>
    <course>Music</course>
    <course>Computers</course>
 </Student>
 <Student>
    <name>B</name>
    <rollNo>2</rollNo>
    <course>Sports</course>
 </Student>
 <Student>
    <name>C</name>
    <rollNo>3</rollNo>
    <course>Sports</course>
            <course>Music</course>
</Student>
<Student>
    <name>D</name>
    <rollNo>4</rollNo>
    <course>GK</course>
</Student>
<Student>
    <name>E</name>
    <rollNo>5</rollNo>
    <course>Computers</course>
            <course>Maths</course>
</Student>
<Student>
    <name>F</name>
    <rollNo>6</rollNo>
    <course>Physics</course>
</Student>
<Student>
    <name>G</name>
    <rollNo>7</rollNo>
    <course>Drama</course>
</Student>
<Student>
    <name>H</name>
    <rollNo>8</rollNo>
    <course>Communication</course>
            <course>Computers</course>
</Student>
<Student>
    <name>I</name>
    <rollNo>9</rollNo>
    <course>Arts</course>
</Student>
<Student>
    <name>J</name>
    <rollNo>10</rollNo>
    <course>Computers</course>
</Student>  
</Students>

Transform.xsl

<?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" indent="yes"/>
<xsl:key name="students-by-course" match="Student" use="course" />
<xsl:template match="Students">
<Courses>
<xsl:for-each select = "Student[count(. | key('students-by-course',    course)[1]) = 1]">
<xsl:sort select="course" />
<course>
 <name>
   <xsl:value-of select="course"/>
 </name>
   <xsl:for-each select="key('students-by-course', course)">
<Student>
<name>
  <xsl:value-of select="name"/>
</name>
<rollNo>
  <xsl:value-of select="rollNo"/>
</rollNo>
</Student>
</xsl:for-each>
</course>
</xsl:for-each>
</Courses>
</xsl:template>
</xsl:stylesheet>

这给了我以下输出

<?xml version="1.0" encoding="UTF-8"?>
<Courses>
 <course>
    <name>Arts</name>
    <Student>
        <name>I</name>
        <rollNo>9</rollNo>
    </Student>
 </course>
 <course>
    <name>Drama</name>
    <Student>
        <name>G</name>
        <rollNo>7</rollNo>
    </Student>
 </course>
 <course>
    <name>GK</name>
    <Student>
        <name>D</name>
        <rollNo>4</rollNo>
    </Student>
 </course>
 <course>
    <name>Music</name>
    <Student>
        <name>A</name>
        <rollNo>1</rollNo>
    </Student>
    <Student>
        <name>C</name>
        <rollNo>3</rollNo>
    </Student>
    <Student>
        <name>E</name>
        <rollNo>5</rollNo>
    </Student>
    <Student>
        <name>H</name>
        <rollNo>8</rollNo>
    </Student>
    <Student>
        <name>J</name>
        <rollNo>10</rollNo>
    </Student>
 </course>
 <course>
    <name>Physics</name>
    <Student>
        <name>F</name>
        <rollNo>6</rollNo>
    </Student>
 </course>
 <course>
    <name>Sports</name>
    <Student>
        <name>B</name>
        <rollNo>2</rollNo>
    </Student>
    <Student>
        <name>C</name>
        <rollNo>3</rollNo>
    </Student>
</course>
</Courses>

正如人们可以看到结果都是错误的。有些课程甚至没有列出,例如计算机和一些学生信息被分配到错误的课程。有人可以帮我吗?

1 个答案:

答案 0 :(得分:0)

我认为在课程中每个学生的注册都会有一个单独的Student元素。否则rollNo代表什么?

无论如何,根据您现在显示的结构,您的样式表应如下所示:

XSLT 1.0

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

<xsl:key name="course" match="course" use="." />

<xsl:template match="Students">
    <Courses>
        <xsl:for-each select="Student/course[count(. | key('course', .)[1]) = 1]">
            <xsl:sort select="." />
            <course>
                <name>
                    <xsl:value-of select="."/>
                </name>
                <xsl:for-each select="key('course', .)">
                    <Student>
                        <xsl:copy-of select="../name | ../rollNo"/>
                    </Student>
                </xsl:for-each>
            </course>
        </xsl:for-each>
    </Courses>
</xsl:template>

</xsl:stylesheet>