使用XSLT将XML转换为XML

时间:2014-08-02 22:32:18

标签: xml xslt

我正在掌握XML,现在正在尝试使用XSLT。我想将XML文件转换为具有不同格式的新XML文件。我已经搞乱了两天了,但正如你可以看到我在下面发布的代码,我没有得到预期的结果。如果有的话,我会继续让它变得更糟。

您可以通过查看我发布的代码来弄清楚我想要改变的内容,但如果没有,这里是我想要做的主要更改:我希望根元素是类并且由类组成元素和“count”属性,用于计算将“Classroom”作为传递的类的数量。课程的“数字”属性应该是类的子元素。我不希望房间成为部分的子元素,而是希望它成为课程的一个属性,以及学分。如果可能的话,我想根据注册大小(从最小到最大)对类元素进行排序。我也想避免使用<xsl:for-each>,因为我听说使用它是不好的。

原始XML文件:

<?xml version="1.0" encoding="UTF-8"?>
<courses>
  <course number="341" credits="4.0">
    <title>Physics</title>
    <section number="01" delivery="Classroom">
      <enrollment>15</enrollment>
      <room>EA244</room>
      <instructor>
        <first>Herman</first>
        <last>Johnson</last>
      </instructor>
    </section>
    <section number="02" delivery="Online">
      <enrollment>10</enrollment>
      <instructor>
        <first>Herman</first>
        <last>Johnson</last>
      </instructor>
      <instructor>
        <first>Mike</first>
        <last>Miller</last>
      </instructor>
    </section>
    <section number="03" delivery="Classroom">
      <enrollment>12</enrollment>
      <room>SH102</room>
      <instructor>
        <first>Allison</first>
        <last>Sweeney</last>
      </instructor>
    </section>
  </course>
  <course number="368" credits="4.0">
      <title>Psychology</title>
    <section number="01" delivery="Classroom">
      <enrollment>9</enrollment>
      <room>AT102</room>
      <instructor>
        <first>Mike</first>
        <last>Miller</last>
      </instructor>
      <instructor>
        <first>Alex</first>
        <last>Holmquist</last>
      </instructor>
    </section>
  </course>
  <course number="375" credits="4.0">
      <title>Biology</title>
    <section number="01" delivery="ITV">
      <enrollment>18</enrollment>
            <room>EA244</room>
      <instructor>
        <first>Mike</first>
        <last>Miller</last>
      </instructor>
    </section>
  </course>
  <course number="385" credits="3.0">
      <title>Calculus</title>
    <section number="01" delivery="Classroom">
      <enrollment>26</enrollment>
            <room>ST108</room>
      <instructor>
        <first>Herman</first>
        <last>Johnson</last>
      </instructor>
    </section>
  </course>
  <course number="413" credits="3.0">
      <title>Chemistry</title>
    <section number="01" delivery="Online">
      <enrollment>10</enrollment>
      <instructor>
        <first>Mike</first>
        <last>Miller</last>
      </instructor>
    </section>
  </course>
</courses>

所需的XML输出:

<?xml version="1.0" encoding="UTF-8"?>
<classes count="4">
  <class credits="4.0" room="AT102">
    <number>368</number>
    <title>Psychology</title>
    <enrollment>9</enrollment>
    <instructor>
      <first>Mike</first>
      <last>Miller</last>
    </instructor>
    <instructor>
      <first>Alex</first>
      <last>Holmquist</last>
    </instructor>
  </class>
  <class credits="4.0" room="SH102">
    <number>341</number>
    <title>Physics</title>
    <enrollment>12</enrollment>
    <instructor>
      <first>Allison </first>
      <last>Sweeney</last>
    </instructor>
  </class>
  <class credits="4.0" room="EA244">
    <number>341</number>
    <title>Physics</title>
    <enrollment>15</enrollment>
    <instructor>
      <first>Herman</first>
      <last>Johnson</last>
    </instructor>
  </class>
  <class credits="3.0" room="ST108">
    <number>385</number>
    <title>Calculus</title>
    <enrollment>26</enrollment>
    <instructor>
      <first>Herman</first>
      <last>Johnson</last>
    </instructor>
  </class>
</classes>

当前XML输出(不需要)

<?xml version="1.0" encoding="UTF-8"?>
<classes count="">
   <class credits="4.0" room="EA244">
      <number>341</number>
      <title>Physics</title>
      <enrollment>15</enrollment>
      <instructor>Herman
        Johnson

        Herman
        Johnson

        Mike
        Miller

        Allison
        Sweeney

        Mike
        Miller

        Alex
        Holmquist

        Mike
        Miller

        Herman
        Johnson

        Mike
        Miller</instructor>
   </class>
</classes>

XSLT文件:

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

<!-- Define output method to XML -->
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />

  <xsl:template match="/">

  <classes>
  <xsl:attribute name="count"> <!--
      <xsl:apply-templates select="/courses/course/section" /> -->
</xsl:attribute>

<class>
  <xsl:attribute name="credits">
      <xsl:value-of select="/courses/course/@credits" />
  </xsl:attribute>
   <xsl:attribute name="room">
       <xsl:value-of select="/courses/course/section/room" />
  </xsl:attribute>
   <number>
       <xsl:value-of select="/courses/course/@number" />
  </number>
   <title>
       <xsl:value-of select="/courses/course/title" />
   </title>
   <enrollment>
       <xsl:value-of select="/courses/course/section/enrollment" />
    </enrollment>
   <instructor>
     <xsl:apply-templates select=" courses/course/section/instructor" />
   </instructor>
</class>
</classes>

<!--template for instructor names -->

<xsl:template match="instructor">
 <xsl:copy/>
</xsl:template>
  <xsl:template match="courses/course/title">
  <xsl:value-of select="title" />
  </xsl:template>
  </xsl:template>
<!--template to count number of classes use "Classroom" delivery -->
<xsl:template match="section">
 <xsl:variable name="classroomCount" select="/{@delivery='Classroom']" />
  <xsl:value-of select="count($classroomCount)" />
  </xsl:template>

  </xsl:stylesheet>

1 个答案:

答案 0 :(得分:1)

认为这可能会做你所描述的。至少收到的结果与所需的结果相同,AFAICT:

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:strip-space elements="*"/>

<xsl:template match="/courses">
    <classes count="{count(course/section[@delivery='Classroom'])}">
        <xsl:apply-templates select="course/section[@delivery='Classroom']">
            <xsl:sort select="enrollment" data-type="number" order="ascending"/>
        </xsl:apply-templates>
    </classes>
</xsl:template>

<xsl:template match="section">
    <class credits="{../@credits}" room="{room}">
        <number><xsl:value-of select="../@number"/></number>
        <xsl:copy-of select="../title | enrollment | instructor"/>
    </class>
</xsl:template>

</xsl:stylesheet>
  

我也想避免使用<xsl:for-each>,因为我听说这对我来说很糟糕   使用

不要相信你所听到的一切。碰巧使用这里不方便,但我会毫不犹豫地使用它。