0

这是我的输入 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>
4

1 回答 1

2

这是一个 XSLT 2.0 样式表,可与 Saxon 9 或 AltovaXML 或 XmlPrime 或任何其他 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 分组

<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.0for-each-group指令以显示等效的基于 XSLT 1.0 键的 Muenchian 分组结构。

于 2013-01-07T13:04:42.550 回答