是否可以使用 XSLT 跳过层次结构中的一个级别?
Is it possible to skip a level in a Hierarchy using XSLT?
层次结构采用 XML 格式,我正在使用 XSLT 转换数据。
例如:如果层次结构有 4 个级别,我想跳过中间的一个级别(比如第 3 级):
Level 1
Level 2
Level 3 - Skip this level
Level 4
Level 5
我应该使用什么元素来达到同样的效果?
附上示例XML文件作为参考输入
<?xml version="1.0" encoding="UTF-8"?>
<Hierarchy>
<Board>
<Name>President</Name>
<Id>ABCDE</Id>
<ParentId></ParentId>
<General>
<Name>President</Name>
<Description>Top level of the Hierarchy</Description>
<Template>LEVEL1</Template>
</General>
</Board>
<Board>
<Name>VP</Name>
<Id>EFGHI</Id>
<ParentId>ABCDE</ParentId>
<General>
<Name>VP</Name>
<Description>Below the President</Description>
<Template>LEVEL2</Template>
</General>
</Board>
<Board>
<Name>Department_Heads</Name>
<Id>JKLMN</Id>
<ParentId>EFGHI</ParentId>
<General>
<Name>Department_Heads</Name>
<Description>Reports to the VP</Description>
<Template>LEVEL3</Template>
</General>
</Board>
<Board>
<Name>Supervisors</Name>
<Id>OPQRS</Id>
<ParentId>JKLMN</ParentId>
<General>
<Name>Supervisors</Name>
<Description>Reports to the Reports to Dep Heads</Description>
<Template>LEVEL4</Template>
</General>
</Board>
<Board>
<Name>Employees</Name>
<Id>TUVWX</Id>
<ParentId>OPQRS</ParentId>
<General>
<Name>Department_Heads</Name>
<Description>Reports to the Reports to Dep Heads</Description>
<Template>LEVEL5</Template>
</General>
</Board>
</Hierarchy>
更新:我正在添加我当前使用的预期输出和 xslt 转换。
预期输出如下:
我目前使用的转换如下:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<Hierarchy>
<xsl:for-each select="Hierarchy/Board">
<xsl:if test="General/Template='LEVEL1'">
<xsl:variable name="Presidentchild" select="Id"/>
<Board>
<Name>
<xsl:value-of select="Name"/>
</Name>
<Template>PRESIDENT</Template>
<Description>
<xsl:value-of select = "General/Description"/>
</Description>
</Board>
</xsl:if>
</xsl:for-each>
<xsl:for-each select="//Board">
<xsl:if test="ParentId = $Presidentchild">
<xsl:if test="General/Template='LEVEL2'">
<Board>
<xsl:variable name="VPchild" select="Id"/>
<Name>
<xsl:value-of select="Name"/>
</Name>
<Template>VICE_PRESIDENT</Template>
<Description>
<xsl:value-of select = "General/Description"/>
</Description>
</Board>
</xsl:if>
</xsl:if>
</xsl:for-each>
</Hierarchy>
</xsl:template>
</xsl:stylesheet>
........直到最后一个元素。
预期输出如下:
<?xml version="1.0" encoding="utf-8"?>
<Hierarchy>
<Board>
<Name>President</Name>
<Template>PRESIDENT</Template>
<Description>Top level of the Hierarchy</Description>
<Board>
<Name>VP</Name>
<Template>VICE_PRESIDENT</Template>
<Description>Below the President</Description>
</Board>
</Board>
</Hierachy>
...以此类推直到最后一个元素。
在对您的问题的评论中,我说这是相当微不足道的。那是因为我认为您的输入 XML 具有层次结构。事实证明,需要通过跟踪从每个 Board
到其父项的交叉引用来派生层次结构。
不过,由于每个 Board
还包含一个(命名错误的)Template
元素,指示其在层次结构中的级别,因此很容易“跳过”某些级别,例如 LEVEL3
在以下样式表中:
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:key name="children" match="Board" use="ParentId" />
<xsl:template match="/Hierarchy">
<xsl:copy>
<xsl:apply-templates select="Board[General/Template='LEVEL1']"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Board">
<xsl:copy>
<xsl:copy-of select="General/*"/>
<xsl:apply-templates select="key('children', Id)"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Board[General/Template='LEVEL3']">
<xsl:apply-templates select="key('children', Id)"/>
</xsl:template>
</xsl:stylesheet>
应用于您的输入示例,这将产生:
结果
<?xml version="1.0" encoding="UTF-8"?>
<Hierarchy>
<Board>
<Name>President</Name>
<Description>Top level of the Hierarchy</Description>
<Template>LEVEL1</Template>
<Board>
<Name>VP</Name>
<Description>Below the President</Description>
<Template>LEVEL2</Template>
<Board>
<Name>Supervisors</Name>
<Description>Reports to the Reports to Dep Heads</Description>
<Template>LEVEL4</Template>
<Board>
<Name>Department_Heads</Name>
<Description>Reports to the Reports to Dep Heads</Description>
<Template>LEVEL5</Template>
</Board>
</Board>
</Board>
</Board>
</Hierarchy>
层次结构采用 XML 格式,我正在使用 XSLT 转换数据。
例如:如果层次结构有 4 个级别,我想跳过中间的一个级别(比如第 3 级):
Level 1
Level 2
Level 3 - Skip this level
Level 4
Level 5
我应该使用什么元素来达到同样的效果?
附上示例XML文件作为参考输入
<?xml version="1.0" encoding="UTF-8"?>
<Hierarchy>
<Board>
<Name>President</Name>
<Id>ABCDE</Id>
<ParentId></ParentId>
<General>
<Name>President</Name>
<Description>Top level of the Hierarchy</Description>
<Template>LEVEL1</Template>
</General>
</Board>
<Board>
<Name>VP</Name>
<Id>EFGHI</Id>
<ParentId>ABCDE</ParentId>
<General>
<Name>VP</Name>
<Description>Below the President</Description>
<Template>LEVEL2</Template>
</General>
</Board>
<Board>
<Name>Department_Heads</Name>
<Id>JKLMN</Id>
<ParentId>EFGHI</ParentId>
<General>
<Name>Department_Heads</Name>
<Description>Reports to the VP</Description>
<Template>LEVEL3</Template>
</General>
</Board>
<Board>
<Name>Supervisors</Name>
<Id>OPQRS</Id>
<ParentId>JKLMN</ParentId>
<General>
<Name>Supervisors</Name>
<Description>Reports to the Reports to Dep Heads</Description>
<Template>LEVEL4</Template>
</General>
</Board>
<Board>
<Name>Employees</Name>
<Id>TUVWX</Id>
<ParentId>OPQRS</ParentId>
<General>
<Name>Department_Heads</Name>
<Description>Reports to the Reports to Dep Heads</Description>
<Template>LEVEL5</Template>
</General>
</Board>
</Hierarchy>
更新:我正在添加我当前使用的预期输出和 xslt 转换。
预期输出如下:
我目前使用的转换如下:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<Hierarchy>
<xsl:for-each select="Hierarchy/Board">
<xsl:if test="General/Template='LEVEL1'">
<xsl:variable name="Presidentchild" select="Id"/>
<Board>
<Name>
<xsl:value-of select="Name"/>
</Name>
<Template>PRESIDENT</Template>
<Description>
<xsl:value-of select = "General/Description"/>
</Description>
</Board>
</xsl:if>
</xsl:for-each>
<xsl:for-each select="//Board">
<xsl:if test="ParentId = $Presidentchild">
<xsl:if test="General/Template='LEVEL2'">
<Board>
<xsl:variable name="VPchild" select="Id"/>
<Name>
<xsl:value-of select="Name"/>
</Name>
<Template>VICE_PRESIDENT</Template>
<Description>
<xsl:value-of select = "General/Description"/>
</Description>
</Board>
</xsl:if>
</xsl:if>
</xsl:for-each>
</Hierarchy>
</xsl:template>
</xsl:stylesheet>
........直到最后一个元素。
预期输出如下:
<?xml version="1.0" encoding="utf-8"?>
<Hierarchy>
<Board>
<Name>President</Name>
<Template>PRESIDENT</Template>
<Description>Top level of the Hierarchy</Description>
<Board>
<Name>VP</Name>
<Template>VICE_PRESIDENT</Template>
<Description>Below the President</Description>
</Board>
</Board>
</Hierachy>
...以此类推直到最后一个元素。
在对您的问题的评论中,我说这是相当微不足道的。那是因为我认为您的输入 XML 具有层次结构。事实证明,需要通过跟踪从每个 Board
到其父项的交叉引用来派生层次结构。
不过,由于每个 Board
还包含一个(命名错误的)Template
元素,指示其在层次结构中的级别,因此很容易“跳过”某些级别,例如 LEVEL3
在以下样式表中:
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:key name="children" match="Board" use="ParentId" />
<xsl:template match="/Hierarchy">
<xsl:copy>
<xsl:apply-templates select="Board[General/Template='LEVEL1']"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Board">
<xsl:copy>
<xsl:copy-of select="General/*"/>
<xsl:apply-templates select="key('children', Id)"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Board[General/Template='LEVEL3']">
<xsl:apply-templates select="key('children', Id)"/>
</xsl:template>
</xsl:stylesheet>
应用于您的输入示例,这将产生:
结果
<?xml version="1.0" encoding="UTF-8"?>
<Hierarchy>
<Board>
<Name>President</Name>
<Description>Top level of the Hierarchy</Description>
<Template>LEVEL1</Template>
<Board>
<Name>VP</Name>
<Description>Below the President</Description>
<Template>LEVEL2</Template>
<Board>
<Name>Supervisors</Name>
<Description>Reports to the Reports to Dep Heads</Description>
<Template>LEVEL4</Template>
<Board>
<Name>Department_Heads</Name>
<Description>Reports to the Reports to Dep Heads</Description>
<Template>LEVEL5</Template>
</Board>
</Board>
</Board>
</Board>
</Hierarchy>