根据条件动态添加节点到节点集

时间:2013-01-07 11:20:50

标签: xslt

这是我输入的xml文件

<Collection>
<Teach>
<DeptNo>5613</DeptNo>
<DeptName>Computers</DeptName>
<SubjectNo>234</SubjectNo>
<SubjectName>XML</SubjectName>
<Teacher>Sai</Teacher>
</Teach>
<Teach>
<DeptNo>5617</DeptNo>
<DeptName>Electronics</DeptName>
<SubjectNo>789</SubjectNo>
<SubjectName>Circuits</SubjectName>
<Teacher>Hari</Teacher>
</Teach>
<Teach>
<DeptNo>5613</DeptNo>
<DeptName>Computers</DeptName>
<SubjectNo>239</SubjectNo>
<SubjectName>XSLT</SubjectName>
<Teacher>Suri</Teacher>
</Teach>
<Teach>
<DeptNo>5689</DeptNo>
<DeptName>Maths</DeptName>
<SubjectNo>749</SubjectNo>
<SubjectName>Trigonometry</SubjectName>
<Teacher>Arya</Teacher>
</Teach>
<Teach>
<DeptNo>5617</DeptNo>
<DeptName>Electronics</DeptName>
<SubjectNo>789</SubjectNo>
<SubjectName>Circuits</SubjectName>
<Teacher>Bharat</Teacher>
</Teach>
</Collection>

现在我想要基于DeptNo的输出xml文件如果相同则检查Subjectno,如果它相同则将教师添加到主题。对主题和部门也这样做。我的输出文件是

<Collection>
<DeptList>
<DeptNo>5613</DeptNo>
<DeptName>Computers</DeptName>
<SubjectList>
<SubjectNo>234</SubjectNo>
<SubjectName>XML</SubjectName>
<TeacherList>
<Teacher>Sai</Teacher>
</TeacherList>
</SubjectList>
<SubjectList>
<SubjectNo>239</SubjectNo>
<SubjectName>XSLT</SubjectName>
<TeacherList>
<Teacher>Suri</Teacher>
</TeacherList>
</SubjectList>
</DeptList>
<DeptList>
<DeptNo>5617</DeptNo>
<DeptName>Electronics</DeptName>
<SubjectList>
<SubjectNo>789</SubjectNo>
<SubjectName>Circuits</SubjectName>
<TeacherList>
<Teacher>Hari</Teacher>
<Teacher>Bharat</Teacher>
</TeacherList>
</SubjectList> 
</DeptList>
<DeptList>
<DeptNo>5689</DeptNo>
<DeptName>Maths</DeptName>
<SubjectList>
<SubjectNo>749</SubjectNo>
<SubjectName>Trigonometry</SubjectName>
<TeacherList>
<Teacher>Arya</Teacher>
</TeacherList>
</SubjectList>
</DeptList>
</Collection>

1 个答案:

答案 0 :(得分:2)

以下是使用Saxon 9或AltovaXML或XmlPrime或任何其他XSLT 2.0处理器运行的XSLT 2.0样式表:

<xsl:stylesheet version="2.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output indent="yes"/>

<xsl:template match="Collection">
  <xsl:copy>
    <xsl:for-each-group select="Teach" group-by="DeptNo">
      <DeptList>
        <xsl:copy-of select="DeptNo, DeptName"/>
        <xsl:for-each-group select="current-group()" group-by="SubjectNo">
          <SubjectList>
            <xsl:copy-of select="SubjectNo, SubjectName"/>
            <TeacherList>
              <xsl:copy-of select="current-group()/Teacher"/>
            </TeacherList>
          </SubjectList>
        </xsl:for-each-group>
      </DeptList>
    </xsl:for-each-group>
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>

[编辑] 如果您需要XSLT 1.0解决方案,可以使用Muechian grouping

<xsl:stylesheet version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output indent="yes"/>

<xsl:key name="deptNo" match="Teach" use="DeptNo"/>
<xsl:key name="deptAndSubject" match="Teach" use="concat(DeptNo, '|', SubjectNo)"/>

<xsl:template match="Collection">
  <xsl:copy>
    <!-- <xsl:for-each-group select="Teach" group-by="DeptNo"> -->
    <xsl:for-each select="Teach[generate-id() = generate-id(key('deptNo', DeptNo)[1])]">
      <DeptList>
        <xsl:copy-of select="DeptNo | DeptName"/>
        <!--  <xsl:for-each-group select="current-group()" group-by="SubjectNo"> -->
        <xsl:for-each select="key('deptNo', DeptNo)[generate-id() = generate-id(key('deptAndSubject', concat(DeptNo, '|', SubjectNo))[1])]">
          <SubjectList>
            <xsl:copy-of select="SubjectNo | SubjectName"/>
            <TeacherList>
              <xsl:copy-of select="key('deptAndSubject', concat(DeptNo, '|', SubjectNo))/Teacher"/>
            </TeacherList>
          </SubjectList>
        </xsl:for-each>
      </DeptList>
    </xsl:for-each>
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>

我故意注释掉XSLT 2.0 for-each-group指令,以显示基于Munkchian分组结构的等效XSLT 1.0密钥。