使用 XSLT 1.0 在 3 个级别上对数据进行分组
Grouping data on 3 levels using XSLT 1.0
我有这个 XML 文件,其中包含日期、会话和 sub-topics。我的前两个级别工作正常,但我无法正确分组第三个级别。
日期的 1 级组
一天中的所有会话都应在该日期下分组
Session_Number 上的 2 级组
具有相同编号的所有会话应分组在一起。
3 级应该在 Abstract_Title 上分组。
如果 Abstract_Title 相同,它应该出现一次,并在其下列出所有作者。
这是我的 XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml"/>
<xsl:strip-space elements="*"/>
<xsl:key name="sessions-by-startDate" match="session" use="startDate"/>
<xsl:key name="sessions-by-Number" match="session" use="concat(startDate, '|', Session_Number)"/>
<xsl:key name="sessions-by-Abstract" match="stamp" use="concat(startDate, '|', Session_Number, '|', Abstract_Title)"/>
<xsl:template match="sessions">
<Guide>
<xsl:for-each select="session[generate-id() = generate-id(key('sessions-by-startDate', startDate)[1])]">
<xsl:text>
</xsl:text><SessionDay>
<startDate><xsl:value-of select="startDate"/></startDate>
<xsl:for-each select="key('sessions-by-startDate', startDate)[generate-id() = generate-id(key('sessions-by-Number', concat(startDate, '|', Session_Number))[1])]">
<sessions>
<xsl:apply-templates select="startTime"/>
<xsl:apply-templates select="Session_Number" />
<xsl:apply-templates select="Session_Title"/><xsl:text>
</xsl:text><TopicTitle>Topics & Faculty</TopicTitle>
<xsl:for-each select="key('sessions-by-Number', concat(startDate, '|', Session_Number))">
<xsl:for-each
select="key('sessions-by-Number', concat(startDate, '|', Session_Number))[count(. | key('sessions-by-Abstract', concat(startDate, '|', Session_Number, '|', Abstract_Title))[1]) = 1]">
<xsl:sort select="Abstract_Title"/>
<xsl:text>
</xsl:text><session>
<xsl:apply-templates select="Abstract_Title"/>
<xsl:for-each select="key('sessions-by-Abstract', concat(startDate, '|', Session_Number, '|', Abstract_Title))">
<xsl:apply-templates select="Author_LastName"/>
</xsl:for-each>
</session>
</xsl:for-each>
</xsl:for-each>
</sessions>
</xsl:for-each>
</SessionDay>
</xsl:for-each>
</Guide>
</xsl:template>
<xsl:template match="startDate">
<startDate><xsl:value-of select="."/></startDate></xsl:template>
<xsl:template match="Session_Title"><xsl:text>
</xsl:text><Session_Title><xsl:value-of select="."/></Session_Title> </xsl:template>
<xsl:template match="Session_Number"><xsl:text>
Session Number </xsl:text><Session_Number><xsl:value-of select="."/> </Session_Number></xsl:template>
<xsl:template match="Abstract_Title"><Abstract_Title><xsl:value-of select="."/> </Abstract_Title></xsl:template>
<xsl:template match="Author_LastName">
<Author_LastName><xsl:value-of select="."/></Author_LastName></xsl:template>
</xsl:stylesheet>
这是一些示例 XML:
<?xml version="1.0" encoding="utf-8"?><sessions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<session><startDate>10/24/2015</startDate><Session_Number>92</Session_Number><Session_Title>Sleep Medicine</Session_Title><Abstract_Title>Concluding Remarks</Abstract_Title><Author_LastName>Stoller</Author_LastName></session>
<session><startDate>10/24/2015</startDate><Session_Number>92</Session_Number><Session_Title>Sleep Medicine</Session_Title><Abstract_Title>Welcome and Introduction</Abstract_Title><Author_LastName>Stoller</Author_LastName></session>
<session><startDate>10/24/2015</startDate><Session_Number>568</Session_Number><Session_Title>Hands-on Simulation</Session_Title><Abstract_Title>Airway</Abstract_Title><Author_LastName>Roth</Author_LastName></session>
<session><startDate>10/24/2015</startDate><Session_Number>568</Session_Number><Session_Title>Hands-on Simulation</Session_Title><Abstract_Title>Airway</Abstract_Title><Author_LastName>Eling</Author_LastName></session>
<session><startDate>10/24/2015</startDate><Session_Number>568</Session_Number><Session_Title>Hands-on Simulation</Session_Title><Abstract_Title>Airway</Abstract_Title><Author_LastName>Bell</Author_LastName></session>
<session><startDate>10/25/2015</startDate><Session_Number>1</Session_Number><Session_Title>Diagnosis of Lung Cancer</Session_Title><Abstract_Title>The Role of EBUS</Abstract_Title><Author_LastName>Silvestri</Author_LastName></session>
<session><startDate>10/25/2015</startDate><Session_Number>1</Session_Number><Session_Title>Diagnosis of Lung Cancer</Session_Title><Abstract_Title>Lung Cancer Staging</Abstract_Title><Author_LastName>Liberman</Author_LastName></session>
<session><startDate>10/25/2015</startDate><Session_Number>1</Session_Number><Session_Title>Diagnosis of Lung Cancer</Session_Title><Abstract_Title>Lung Cancer Staging</Abstract_Title><Author_LastName>Hong</Author_LastName></session>
<session><startDate>10/25/2015</startDate><Session_Number>9</Session_Number><Session_Title>Non-small Cell Lung Cancer??</Session_Title><Abstract_Title>Imaging </Abstract_Title><Author_LastName>Duong</Author_LastName></session>
</sessions>
结果 XML 应该如下所示:
<?xml version="1.0" encoding="utf-8"?><Guide>
<SessionDay>
<startDate>10/24/2015</startDate>
<sessions>Session Number <Session_Number>92</Session_Number>
<Session_Title>Sleep Medicine</Session_Title>
<TopicTitle>Topics & Faculty</TopicTitle>
<session><Abstract_Title>Concluding Remarks</Abstract_Title>
<Author_LastName>Stoller</Author_LastName></session>
<session><Abstract_Title>Welcome and Introduction</Abstract_Title>
<Author_LastName>Stoller</Author_LastName></session>
</sessions>
<sessions>Session Number <Session_Number>568</Session_Number>
<Session_Title>Hands-on Simulation</Session_Title>
<TopicTitle>Topics & Faculty</TopicTitle>
<session><Abstract_Title>Airway</Abstract_Title>
<Author_LastName>Roth</Author_LastName>
<Author_LastName>Eling</Author_LastName>
<Author_LastName>Bell</Author_LastName></session>
</sessions></SessionDay>
<SessionDay><startDate>10/25/2015</startDate>
<sessions>Session Number <Session_Number>1</Session_Number>
<Session_Title>Diagnosis of Lung Cancer</Session_Title>
<TopicTitle>Topics & Faculty</TopicTitle>
<session><Abstract_Title>The Role of EBUS</Abstract_Title>
<Author_LastName>Silvestri</Author_LastName></session>
<session><Abstract_Title>Lung Cancer Staging</Abstract_Title>
<Author_LastName>Liberman</Author_LastName></session>
<session><Abstract_Title>Lung Cancer Diagnosis</Abstract_Title>
<Author_LastName>Hong</Author_LastName></session></sessions>
<sessions>Session Number <Session_Number>9</Session_Number>
<Session_Title>Non-small Cell Lung Cancer??</Session_Title>
<TopicTitle>Topics & Faculty</TopicTitle>
<session><Abstract_Title>Imaging</Abstract_Title>
<Author_LastName>Duong</Author_LastName></session>
</sessions></SessionDay>
</Guide>
我当前的 XSLT 可以很好地创建前两组。但是我得到了重复的 Abstract_Title 元素。相反,它应该只有一个唯一的 Abstract_Title 元素,然后列出所有唯一的作者姓名。
我需要添加第三个密钥并生成另一个 ID。但我不确定将它插入何处或需要如何编写。任何帮助将不胜感激
您的 XSLT 存在几个问题:
1.) xsl:key name="sessions-by-Abstract"
匹配 stamp
而不是 session
,所以密钥不匹配任何内容。
2.) for-each <xsl:for-each select="key('sessions-by-Number', concat(startDate, '|', Session_Number))">
是 selecting 来自 sessions-by-Number 键的项目,然后使用来自相同键的 select 作为标准下一个 xsl:for-each
,导致重复。
3.) 如果您打算在输出中插入换行符,最好使用实体而不是换行符。例如:<xsl:text>
</xsl:text>
。这样,如果您的 XSLT 是代码格式的,您就不会 运行 丢失换行符或在输出中添加额外空格的风险。但是,如果您只是想更好地格式化输出 XML,使用 <xsl:output indent="yes"/>
会更容易,它会漂亮地打印(格式化和缩进)XML。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" />
<xsl:strip-space elements="*"/>
<xsl:key name="sessions-by-startDate" match="session" use="startDate"/>
<xsl:key name="sessions-by-Number" match="session" use="concat(startDate, '|', Session_Number)"/>
<xsl:key name="sessions-by-Abstract" match="session" use="concat(startDate, '|', Session_Number, '|', Abstract_Title)"/>
<xsl:template match="sessions">
<Guide>
<xsl:for-each select="session[generate-id() = generate-id(key('sessions-by-startDate', startDate)[1])]">
<xsl:text>
</xsl:text>
<SessionDay>
<startDate><xsl:value-of select="startDate"/></startDate>
<xsl:for-each select="key('sessions-by-startDate', startDate)[generate-id() = generate-id(key('sessions-by-Number', concat(startDate, '|', Session_Number))[1])]">
<sessions>
<xsl:apply-templates select="startTime"/>
<xsl:apply-templates select="Session_Number"/>
<xsl:apply-templates select="Session_Title"/>
<xsl:text>
</xsl:text>
<TopicTitle>Topics & Faculty</TopicTitle>
<xsl:for-each
select="key('sessions-by-Number', concat(startDate, '|', Session_Number))[count(. | key('sessions-by-Abstract', concat(startDate, '|', Session_Number, '|', Abstract_Title))[1]) = 1]">
<xsl:sort select="Abstract_Title"/>
<xsl:text>
</xsl:text>
<session>
<xsl:apply-templates select="Abstract_Title"/>
<xsl:for-each
select="key('sessions-by-Abstract', concat(startDate, '|', Session_Number, '|', Abstract_Title))">
<xsl:apply-templates select="Author_LastName"/>
</xsl:for-each>
</session>
</xsl:for-each>
</sessions>
</xsl:for-each>
</SessionDay>
</xsl:for-each>
</Guide>
</xsl:template>
<xsl:template match="startDate">
<startDate><xsl:value-of select="."/></startDate>
</xsl:template>
<xsl:template match="Session_Title">
<xsl:text>
</xsl:text>
<Session_Title><xsl:value-of select="."/></Session_Title>
</xsl:template>
<xsl:template match="Session_Number">
<xsl:text>Session Number </xsl:text>
<Session_Number>
<xsl:value-of select="."/>
</Session_Number>
</xsl:template>
<xsl:template match="Abstract_Title"><Abstract_Title><xsl:value-of select="."/>
</Abstract_Title>
</xsl:template>
<xsl:template match="Author_LastName">
<Author_LastName><xsl:value-of select="."/></Author_LastName>
</xsl:template>
</xsl:stylesheet>
我有这个 XML 文件,其中包含日期、会话和 sub-topics。我的前两个级别工作正常,但我无法正确分组第三个级别。
日期的 1 级组 一天中的所有会话都应在该日期下分组
Session_Number 上的 2 级组 具有相同编号的所有会话应分组在一起。
3 级应该在 Abstract_Title 上分组。 如果 Abstract_Title 相同,它应该出现一次,并在其下列出所有作者。
这是我的 XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml"/>
<xsl:strip-space elements="*"/>
<xsl:key name="sessions-by-startDate" match="session" use="startDate"/>
<xsl:key name="sessions-by-Number" match="session" use="concat(startDate, '|', Session_Number)"/>
<xsl:key name="sessions-by-Abstract" match="stamp" use="concat(startDate, '|', Session_Number, '|', Abstract_Title)"/>
<xsl:template match="sessions">
<Guide>
<xsl:for-each select="session[generate-id() = generate-id(key('sessions-by-startDate', startDate)[1])]">
<xsl:text>
</xsl:text><SessionDay>
<startDate><xsl:value-of select="startDate"/></startDate>
<xsl:for-each select="key('sessions-by-startDate', startDate)[generate-id() = generate-id(key('sessions-by-Number', concat(startDate, '|', Session_Number))[1])]">
<sessions>
<xsl:apply-templates select="startTime"/>
<xsl:apply-templates select="Session_Number" />
<xsl:apply-templates select="Session_Title"/><xsl:text>
</xsl:text><TopicTitle>Topics & Faculty</TopicTitle>
<xsl:for-each select="key('sessions-by-Number', concat(startDate, '|', Session_Number))">
<xsl:for-each
select="key('sessions-by-Number', concat(startDate, '|', Session_Number))[count(. | key('sessions-by-Abstract', concat(startDate, '|', Session_Number, '|', Abstract_Title))[1]) = 1]">
<xsl:sort select="Abstract_Title"/>
<xsl:text>
</xsl:text><session>
<xsl:apply-templates select="Abstract_Title"/>
<xsl:for-each select="key('sessions-by-Abstract', concat(startDate, '|', Session_Number, '|', Abstract_Title))">
<xsl:apply-templates select="Author_LastName"/>
</xsl:for-each>
</session>
</xsl:for-each>
</xsl:for-each>
</sessions>
</xsl:for-each>
</SessionDay>
</xsl:for-each>
</Guide>
</xsl:template>
<xsl:template match="startDate">
<startDate><xsl:value-of select="."/></startDate></xsl:template>
<xsl:template match="Session_Title"><xsl:text>
</xsl:text><Session_Title><xsl:value-of select="."/></Session_Title> </xsl:template>
<xsl:template match="Session_Number"><xsl:text>
Session Number </xsl:text><Session_Number><xsl:value-of select="."/> </Session_Number></xsl:template>
<xsl:template match="Abstract_Title"><Abstract_Title><xsl:value-of select="."/> </Abstract_Title></xsl:template>
<xsl:template match="Author_LastName">
<Author_LastName><xsl:value-of select="."/></Author_LastName></xsl:template>
</xsl:stylesheet>
这是一些示例 XML:
<?xml version="1.0" encoding="utf-8"?><sessions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<session><startDate>10/24/2015</startDate><Session_Number>92</Session_Number><Session_Title>Sleep Medicine</Session_Title><Abstract_Title>Concluding Remarks</Abstract_Title><Author_LastName>Stoller</Author_LastName></session>
<session><startDate>10/24/2015</startDate><Session_Number>92</Session_Number><Session_Title>Sleep Medicine</Session_Title><Abstract_Title>Welcome and Introduction</Abstract_Title><Author_LastName>Stoller</Author_LastName></session>
<session><startDate>10/24/2015</startDate><Session_Number>568</Session_Number><Session_Title>Hands-on Simulation</Session_Title><Abstract_Title>Airway</Abstract_Title><Author_LastName>Roth</Author_LastName></session>
<session><startDate>10/24/2015</startDate><Session_Number>568</Session_Number><Session_Title>Hands-on Simulation</Session_Title><Abstract_Title>Airway</Abstract_Title><Author_LastName>Eling</Author_LastName></session>
<session><startDate>10/24/2015</startDate><Session_Number>568</Session_Number><Session_Title>Hands-on Simulation</Session_Title><Abstract_Title>Airway</Abstract_Title><Author_LastName>Bell</Author_LastName></session>
<session><startDate>10/25/2015</startDate><Session_Number>1</Session_Number><Session_Title>Diagnosis of Lung Cancer</Session_Title><Abstract_Title>The Role of EBUS</Abstract_Title><Author_LastName>Silvestri</Author_LastName></session>
<session><startDate>10/25/2015</startDate><Session_Number>1</Session_Number><Session_Title>Diagnosis of Lung Cancer</Session_Title><Abstract_Title>Lung Cancer Staging</Abstract_Title><Author_LastName>Liberman</Author_LastName></session>
<session><startDate>10/25/2015</startDate><Session_Number>1</Session_Number><Session_Title>Diagnosis of Lung Cancer</Session_Title><Abstract_Title>Lung Cancer Staging</Abstract_Title><Author_LastName>Hong</Author_LastName></session>
<session><startDate>10/25/2015</startDate><Session_Number>9</Session_Number><Session_Title>Non-small Cell Lung Cancer??</Session_Title><Abstract_Title>Imaging </Abstract_Title><Author_LastName>Duong</Author_LastName></session>
</sessions>
结果 XML 应该如下所示:
<?xml version="1.0" encoding="utf-8"?><Guide>
<SessionDay>
<startDate>10/24/2015</startDate>
<sessions>Session Number <Session_Number>92</Session_Number>
<Session_Title>Sleep Medicine</Session_Title>
<TopicTitle>Topics & Faculty</TopicTitle>
<session><Abstract_Title>Concluding Remarks</Abstract_Title>
<Author_LastName>Stoller</Author_LastName></session>
<session><Abstract_Title>Welcome and Introduction</Abstract_Title>
<Author_LastName>Stoller</Author_LastName></session>
</sessions>
<sessions>Session Number <Session_Number>568</Session_Number>
<Session_Title>Hands-on Simulation</Session_Title>
<TopicTitle>Topics & Faculty</TopicTitle>
<session><Abstract_Title>Airway</Abstract_Title>
<Author_LastName>Roth</Author_LastName>
<Author_LastName>Eling</Author_LastName>
<Author_LastName>Bell</Author_LastName></session>
</sessions></SessionDay>
<SessionDay><startDate>10/25/2015</startDate>
<sessions>Session Number <Session_Number>1</Session_Number>
<Session_Title>Diagnosis of Lung Cancer</Session_Title>
<TopicTitle>Topics & Faculty</TopicTitle>
<session><Abstract_Title>The Role of EBUS</Abstract_Title>
<Author_LastName>Silvestri</Author_LastName></session>
<session><Abstract_Title>Lung Cancer Staging</Abstract_Title>
<Author_LastName>Liberman</Author_LastName></session>
<session><Abstract_Title>Lung Cancer Diagnosis</Abstract_Title>
<Author_LastName>Hong</Author_LastName></session></sessions>
<sessions>Session Number <Session_Number>9</Session_Number>
<Session_Title>Non-small Cell Lung Cancer??</Session_Title>
<TopicTitle>Topics & Faculty</TopicTitle>
<session><Abstract_Title>Imaging</Abstract_Title>
<Author_LastName>Duong</Author_LastName></session>
</sessions></SessionDay>
</Guide>
我当前的 XSLT 可以很好地创建前两组。但是我得到了重复的 Abstract_Title 元素。相反,它应该只有一个唯一的 Abstract_Title 元素,然后列出所有唯一的作者姓名。
我需要添加第三个密钥并生成另一个 ID。但我不确定将它插入何处或需要如何编写。任何帮助将不胜感激
您的 XSLT 存在几个问题:
1.) xsl:key name="sessions-by-Abstract"
匹配 stamp
而不是 session
,所以密钥不匹配任何内容。
2.) for-each <xsl:for-each select="key('sessions-by-Number', concat(startDate, '|', Session_Number))">
是 selecting 来自 sessions-by-Number 键的项目,然后使用来自相同键的 select 作为标准下一个 xsl:for-each
,导致重复。
3.) 如果您打算在输出中插入换行符,最好使用实体而不是换行符。例如:<xsl:text>
</xsl:text>
。这样,如果您的 XSLT 是代码格式的,您就不会 运行 丢失换行符或在输出中添加额外空格的风险。但是,如果您只是想更好地格式化输出 XML,使用 <xsl:output indent="yes"/>
会更容易,它会漂亮地打印(格式化和缩进)XML。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" />
<xsl:strip-space elements="*"/>
<xsl:key name="sessions-by-startDate" match="session" use="startDate"/>
<xsl:key name="sessions-by-Number" match="session" use="concat(startDate, '|', Session_Number)"/>
<xsl:key name="sessions-by-Abstract" match="session" use="concat(startDate, '|', Session_Number, '|', Abstract_Title)"/>
<xsl:template match="sessions">
<Guide>
<xsl:for-each select="session[generate-id() = generate-id(key('sessions-by-startDate', startDate)[1])]">
<xsl:text>
</xsl:text>
<SessionDay>
<startDate><xsl:value-of select="startDate"/></startDate>
<xsl:for-each select="key('sessions-by-startDate', startDate)[generate-id() = generate-id(key('sessions-by-Number', concat(startDate, '|', Session_Number))[1])]">
<sessions>
<xsl:apply-templates select="startTime"/>
<xsl:apply-templates select="Session_Number"/>
<xsl:apply-templates select="Session_Title"/>
<xsl:text>
</xsl:text>
<TopicTitle>Topics & Faculty</TopicTitle>
<xsl:for-each
select="key('sessions-by-Number', concat(startDate, '|', Session_Number))[count(. | key('sessions-by-Abstract', concat(startDate, '|', Session_Number, '|', Abstract_Title))[1]) = 1]">
<xsl:sort select="Abstract_Title"/>
<xsl:text>
</xsl:text>
<session>
<xsl:apply-templates select="Abstract_Title"/>
<xsl:for-each
select="key('sessions-by-Abstract', concat(startDate, '|', Session_Number, '|', Abstract_Title))">
<xsl:apply-templates select="Author_LastName"/>
</xsl:for-each>
</session>
</xsl:for-each>
</sessions>
</xsl:for-each>
</SessionDay>
</xsl:for-each>
</Guide>
</xsl:template>
<xsl:template match="startDate">
<startDate><xsl:value-of select="."/></startDate>
</xsl:template>
<xsl:template match="Session_Title">
<xsl:text>
</xsl:text>
<Session_Title><xsl:value-of select="."/></Session_Title>
</xsl:template>
<xsl:template match="Session_Number">
<xsl:text>Session Number </xsl:text>
<Session_Number>
<xsl:value-of select="."/>
</Session_Number>
</xsl:template>
<xsl:template match="Abstract_Title"><Abstract_Title><xsl:value-of select="."/>
</Abstract_Title>
</xsl:template>
<xsl:template match="Author_LastName">
<Author_LastName><xsl:value-of select="."/></Author_LastName>
</xsl:template>
</xsl:stylesheet>