XML/XSL - 用于在组内嵌套组的 Muenchian 方法
XML/XSL - Muenchian method for nesting groups within groups
我正在处理 XSL 样式表,学生按以下顺序分组:
学院->级别->系->主任->专业->学生
所以基本上结构是 "groups within groups"。如果以下内容有意义,请告诉我。如果您需要说明,请告诉我!
这是我正在尝试转换的原始 XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<dataroot>
<student>
<name_sort>Doe, John</name_sort>
<name>John Doe</name>
<level>Undergrad</level>
<concentration>Studio Art</concentration>
<college>College 1</college>
<department>Department 1</department>
<chair>Chair Name</chair>
</student>
<student>
<name_sort>James, Lisa</name_sort>
<name>Lisa James</name>
<level>Undergrad</level>
<concentration>Studio Art</concentration>
<college>College 1</college>
<department>Department 1</department>
<chair>Chair Name</chair>
</student>
<dataroot>
XML 使用 XSL 样式表的输出:
<Root>
<!-- Group by College -->
<college>College 1</college>
<!-- Group by Level -->
<level>Undergraduate</level>
<!-- Group by Department -->
<department>Department 1</department>
<!-- Group by Chair -->
<chair>Chair Name</chair>
<!-- Group by Concentration -->
<concentration>Studio Art</concentration>
<!-- List Students with matching concentration under parent groups -->
<student>
<name>John Doe</name>
</student>
<student>
<name>Lisa James</name>
</student>
<!-- Repeat loop -->
</Root>
这是我的尝试,但学生没有正确分组。一些 "undegraduate" 的学生出现在 "graduate" 下,一些集中组重复...
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- Keys for grouping -->
<xsl:key name="colleges" match="student" use="college"/>
<xsl:key name="levels" match="student" use="level"/>
<xsl:key name="departments" match="student" use="department"/>
<xsl:key name="chairs" match="student" use="chair"/>
<xsl:key name="concentrations" match="student" use="concentration"/>
<xsl:template match="/dataroot">
<Root>
<xsl:for-each select="student[generate-id() = generate-id(key('colleges', college)[1])]">
<xsl:sort select="college" order="ascending"/>
<xsl:for-each select="key('colleges', college)[generate-id() = generate-id(key('levels', level)[1])]">
<xsl:sort select="level" order="ascending"/>
<college><xsl:value-of select="college"/></college>
<xsl:text>
</xsl:text>
<level><xsl:value-of select="level"/> degree recipients</level>
<xsl:text>
</xsl:text>
<xsl:for-each select="key('levels', level)[generate-id() = generate-id(key('departments', department)[1])]">
<xsl:sort select="department" order="ascending"/>
<department><xsl:value-of select="department"/></department>
<xsl:text>
</xsl:text>
<xsl:for-each select="key('departments', department)[generate-id() = generate-id(key('chairs', chair)[1])]">
<xsl:sort select="chair" order="ascending"/>
<chair><xsl:value-of select="chair"/></chair>
<xsl:text>
</xsl:text>
<xsl:for-each select="key('chairs', chair)[generate-id() = generate-id(key('concentrations', concentration)[1])]">
<xsl:sort select="concentration" order="ascending"/>
<concentration><xsl:value-of select="concentration"/></concentration>
<xsl:text>
</xsl:text>
<xsl:for-each select="key('concentrations', concentration)">
<xsl:sort select="name_sort" order="ascending"/>
<student>
<name><xsl:value-of select="name"/></name>
<xsl:text>
</xsl:text>
</student>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
</Root>
</xsl:template>
谁能帮帮我?
使用 XSLT 2 或 3 可以很容易地嵌套 xsl:for-each-group
您尝试使用 xsl:for-each
的方式,但是对于 XSLT 1 和 Muenchian 分组,您需要让第二级键包含第一级级别键,例如
<xsl:key name="colleges" match="student" use="college"/>
<xsl:key name="levels" match="student" use="concat(college, '|', level)"/>
并使用例如
<xsl:for-each select="key('colleges', college)[generate-id() = generate-id(key('levels', concat(college, '|', level))[1])]">
然后你需要对第三级密钥使用相同的方法
<xsl:key name="departments" match="student" use="concat(department, '|', college, '|', level)"/>
和
<xsl:for-each select="key('levels', concat(college, '|', level))[generate-id() = generate-id(key('departments', concat(department, '|', college, '|', level))[1])]">
等等。
考虑使用单个键连接所有需要的父分组。无需多个嵌套 for:each
调用。 运行 需要在 <xsl:apply-templates>
内排序。但是,如果您有很多分组,您将需要一个分组容器元素作为根元素。下面使用 <students>
和调整后的 XML 进行演示。
XML
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<dataroot>
<student>
<name_sort>Doe, John</name_sort>
<name>John Doe</name>
<level>Undergrad</level>
<concentration>Studio Art</concentration>
<college>College 1</college>
<department>Department 1</department>
<chair>Chair Name</chair>
</student>
<student>
<name_sort>James, Lisa</name_sort>
<name>Lisa James</name>
<level>Undergrad</level>
<concentration>Economics</concentration>
<college>College 1</college>
<department>Department 1</department>
<chair>Chair Name</chair>
</student>
<student>
<name_sort>Doe, Jane</name_sort>
<name>Jane Doe</name>
<level>Undergrad</level>
<concentration>Economics</concentration>
<college>College 1</college>
<department>Department 1</department>
<chair>Chair Name</chair>
</student>
</dataroot>
XSLT
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" method="xml"/>
<xsl:strip-space elements="*"/>
<!-- single key for grouping -->
<xsl:key name="concatkey" match="student" use="concat(college, level, department, chair, concentration)"/>
<xsl:template match="/dataroot">
<root>
<xsl:apply-templates select="student[generate-id() = generate-id(key('concatkey',
concat(college, level, department, chair, concentration)))]"/>
</root>
</xsl:template>
<xsl:template match="student">
<students>
<xsl:copy-of select="college"/>
<xsl:copy-of select="level"/>
<xsl:copy-of select="department"/>
<xsl:copy-of select="chair"/>
<xsl:copy-of select="concentration"/>
<xsl:for-each select="key('concatkey', concat(college, level, department, chair, concentration))">
<student><xsl:copy-of select="name"/></student>
</xsl:for-each>
</students>
</xsl:template>
</xsl:stylesheet>
<?xml version="1.0" encoding="utf-8"?>
<root>
<students>
<college>College 1</college>
<level>Undergrad</level>
<department>Department 1</department>
<chair>Chair Name</chair>
<concentration>Economics</concentration>
<student>
<name>Lisa James</name>
</student>
<student>
<name>Jane Doe</name>
</student>
</students>
<students>
<college>College 1</college>
<level>Undergrad</level>
<department>Department 1</department>
<chair>Chair Name</chair>
<concentration>Studio Art</concentration>
<student>
<name>John Doe</name>
</student>
</students>
</root>
我正在处理 XSL 样式表,学生按以下顺序分组:
学院->级别->系->主任->专业->学生
所以基本上结构是 "groups within groups"。如果以下内容有意义,请告诉我。如果您需要说明,请告诉我!
这是我正在尝试转换的原始 XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<dataroot>
<student>
<name_sort>Doe, John</name_sort>
<name>John Doe</name>
<level>Undergrad</level>
<concentration>Studio Art</concentration>
<college>College 1</college>
<department>Department 1</department>
<chair>Chair Name</chair>
</student>
<student>
<name_sort>James, Lisa</name_sort>
<name>Lisa James</name>
<level>Undergrad</level>
<concentration>Studio Art</concentration>
<college>College 1</college>
<department>Department 1</department>
<chair>Chair Name</chair>
</student>
<dataroot>
XML 使用 XSL 样式表的输出:
<Root>
<!-- Group by College -->
<college>College 1</college>
<!-- Group by Level -->
<level>Undergraduate</level>
<!-- Group by Department -->
<department>Department 1</department>
<!-- Group by Chair -->
<chair>Chair Name</chair>
<!-- Group by Concentration -->
<concentration>Studio Art</concentration>
<!-- List Students with matching concentration under parent groups -->
<student>
<name>John Doe</name>
</student>
<student>
<name>Lisa James</name>
</student>
<!-- Repeat loop -->
</Root>
这是我的尝试,但学生没有正确分组。一些 "undegraduate" 的学生出现在 "graduate" 下,一些集中组重复...
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- Keys for grouping -->
<xsl:key name="colleges" match="student" use="college"/>
<xsl:key name="levels" match="student" use="level"/>
<xsl:key name="departments" match="student" use="department"/>
<xsl:key name="chairs" match="student" use="chair"/>
<xsl:key name="concentrations" match="student" use="concentration"/>
<xsl:template match="/dataroot">
<Root>
<xsl:for-each select="student[generate-id() = generate-id(key('colleges', college)[1])]">
<xsl:sort select="college" order="ascending"/>
<xsl:for-each select="key('colleges', college)[generate-id() = generate-id(key('levels', level)[1])]">
<xsl:sort select="level" order="ascending"/>
<college><xsl:value-of select="college"/></college>
<xsl:text>
</xsl:text>
<level><xsl:value-of select="level"/> degree recipients</level>
<xsl:text>
</xsl:text>
<xsl:for-each select="key('levels', level)[generate-id() = generate-id(key('departments', department)[1])]">
<xsl:sort select="department" order="ascending"/>
<department><xsl:value-of select="department"/></department>
<xsl:text>
</xsl:text>
<xsl:for-each select="key('departments', department)[generate-id() = generate-id(key('chairs', chair)[1])]">
<xsl:sort select="chair" order="ascending"/>
<chair><xsl:value-of select="chair"/></chair>
<xsl:text>
</xsl:text>
<xsl:for-each select="key('chairs', chair)[generate-id() = generate-id(key('concentrations', concentration)[1])]">
<xsl:sort select="concentration" order="ascending"/>
<concentration><xsl:value-of select="concentration"/></concentration>
<xsl:text>
</xsl:text>
<xsl:for-each select="key('concentrations', concentration)">
<xsl:sort select="name_sort" order="ascending"/>
<student>
<name><xsl:value-of select="name"/></name>
<xsl:text>
</xsl:text>
</student>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
</Root>
</xsl:template>
谁能帮帮我?
使用 XSLT 2 或 3 可以很容易地嵌套 xsl:for-each-group
您尝试使用 xsl:for-each
的方式,但是对于 XSLT 1 和 Muenchian 分组,您需要让第二级键包含第一级级别键,例如
<xsl:key name="colleges" match="student" use="college"/>
<xsl:key name="levels" match="student" use="concat(college, '|', level)"/>
并使用例如
<xsl:for-each select="key('colleges', college)[generate-id() = generate-id(key('levels', concat(college, '|', level))[1])]">
然后你需要对第三级密钥使用相同的方法
<xsl:key name="departments" match="student" use="concat(department, '|', college, '|', level)"/>
和
<xsl:for-each select="key('levels', concat(college, '|', level))[generate-id() = generate-id(key('departments', concat(department, '|', college, '|', level))[1])]">
等等。
考虑使用单个键连接所有需要的父分组。无需多个嵌套 for:each
调用。 运行 需要在 <xsl:apply-templates>
内排序。但是,如果您有很多分组,您将需要一个分组容器元素作为根元素。下面使用 <students>
和调整后的 XML 进行演示。
XML
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<dataroot>
<student>
<name_sort>Doe, John</name_sort>
<name>John Doe</name>
<level>Undergrad</level>
<concentration>Studio Art</concentration>
<college>College 1</college>
<department>Department 1</department>
<chair>Chair Name</chair>
</student>
<student>
<name_sort>James, Lisa</name_sort>
<name>Lisa James</name>
<level>Undergrad</level>
<concentration>Economics</concentration>
<college>College 1</college>
<department>Department 1</department>
<chair>Chair Name</chair>
</student>
<student>
<name_sort>Doe, Jane</name_sort>
<name>Jane Doe</name>
<level>Undergrad</level>
<concentration>Economics</concentration>
<college>College 1</college>
<department>Department 1</department>
<chair>Chair Name</chair>
</student>
</dataroot>
XSLT
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" method="xml"/>
<xsl:strip-space elements="*"/>
<!-- single key for grouping -->
<xsl:key name="concatkey" match="student" use="concat(college, level, department, chair, concentration)"/>
<xsl:template match="/dataroot">
<root>
<xsl:apply-templates select="student[generate-id() = generate-id(key('concatkey',
concat(college, level, department, chair, concentration)))]"/>
</root>
</xsl:template>
<xsl:template match="student">
<students>
<xsl:copy-of select="college"/>
<xsl:copy-of select="level"/>
<xsl:copy-of select="department"/>
<xsl:copy-of select="chair"/>
<xsl:copy-of select="concentration"/>
<xsl:for-each select="key('concatkey', concat(college, level, department, chair, concentration))">
<student><xsl:copy-of select="name"/></student>
</xsl:for-each>
</students>
</xsl:template>
</xsl:stylesheet>
<?xml version="1.0" encoding="utf-8"?>
<root>
<students>
<college>College 1</college>
<level>Undergrad</level>
<department>Department 1</department>
<chair>Chair Name</chair>
<concentration>Economics</concentration>
<student>
<name>Lisa James</name>
</student>
<student>
<name>Jane Doe</name>
</student>
</students>
<students>
<college>College 1</college>
<level>Undergrad</level>
<department>Department 1</department>
<chair>Chair Name</chair>
<concentration>Studio Art</concentration>
<student>
<name>John Doe</name>
</student>
</students>
</root>