【发布时间】:2021-04-18 09:28:51
【问题描述】:
假设我对汽车公司的不同部分有一个层次结构。
例如
1. Audi
1.1 Engine
1.1.1 Piston
1.1.2 Crankshaft
1.2 Transmission
1.2.1 Gears
1.2.2 Shift
2. Ferrari
2.1 Engine
2.1.1 Piston
2.1.2 Crankshaft
2.2 Transmission
2.2.1 Gears
2.2.2 Shift
3. Ford
3.1 Engine
3.1.1 Piston
3.1.2 Crankshaft
3.2 Transmission
3.2.1 Gears
现在输出必须只包含其中包含“Shift”的层次结构。其余的不能在我的输出中看到。输出应如下所示:
-
奥迪 1.2 传输 1.2.2 移位
-
法拉利 2.2 传输 2.2.2 换档
我可以使用任何特定元素来获得此输出吗?
更新示例 XML 输入文件
<?xml version="1.0" encoding="UTF-8"?>
<Hierarchy>
<Board>
<Name>Audi</Name>
<Id>ABCDE</Id>
<ParentId></ParentId>
<General>
<Name>Audi</Name>
<Description>Car brand</Description>
<Template>LEVEL1</Template>
</General>
</Board>
<Board>
<Name>Engine</Name>
<Id>EFGHI</Id>
<ParentId>ABCDE</ParentId>
<General>
<Name>Engine</Name>
<Description>Part of Car</Description>
<Template>LEVEL2</Template>
</General>
</Board>
<Board>
<Name>Piston</Name>
<Id>JKLMN</Id>
<ParentId>EFGHI</ParentId>
<General>
<Name>Department_Heads</Name>
<Description>Part of Engine</Description>
<Template>LEVEL3</Template>
</General>
</Board>
<Board>
<Name>Crankshaft</Name>
<Id>OPQRS</Id>
<ParentId>EFGHI</ParentId>
<General>
<Name>Department_Heads</Name>
<Description>Part of Engine</Description>
<Template>LEVEL3</Template>
</General>
</Board>
<Board>
<Name>Transmission</Name>
<Id>TUVWX</Id>
<ParentId>ABCDE</ParentId>
<General>
<Name>Transmission</Name>
<Description>Part of Car</Description>
<Template>LEVEL2</Template>
</General>
</Board>
<Board>
<Name>Gear</Name>
<Id>CSDKL</Id>
<ParentId>TUVWX</ParentId>
<General>
<Name>Gear</Name>
<Description>Part of Transmission</Description>
<Template>LEVEL3</Template>
</General>
</Board>
<Board>
<Name>Shift</Name>
<Id>SDKLFH</Id>
<ParentId>TUVWX</ParentId>
<General>
<Name>Shift</Name>
<Description>Part of Transmission</Description>
<Template>LEVEL3</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="blabla" select="Id"/>
<Board>
<Name>
<xsl:value-of select="Name"/>
</Name>
<Template>CAR1</Template>
<Description>
<xsl:value-of select = "General/Description"/>
</Description>
<xsl:for-each select="//Board">
<xsl:if test="ParentId = $blabla">
<Board>
<xsl:variable name="blablablablabla" select="Id"/>
<Name>
<xsl:value-of select="Name"/>
</Name>
<Template>TRANSMISSION</Template>
<Description>
<xsl:value-of select = "General/Description"/>
</Description>
<xsl:for-each select="//Board">
<xsl:if test="ParentId = $blablablablabla">
<Board>
<xsl:variable name="blablablablablablablablablablablabla" select="Id"/>
<Name>
<xsl:value-of select="Name"/>
</Name>
<Template>SHIFT</Template>
<Description>
<xsl:value-of select = "General/Description"/>
</Description>
</Board>
</xsl:if>
</xsl:for-each>
</Board>
</xsl:if>
</xsl:for-each>
</Board>
</xsl:if>
</xsl:for-each>
</Hierarchy>
</xsl:template>
</xsl:stylesheet>
请注意,我刚刚提到了整个 XSLT 的特定部分。通常当我使用它时它工作正常,但是当数据增加时,比如上面的 50 万个元素,并且当“Shift”处于不同级别(这里它在层次结构树中的第 3 级)时,由于某种原因它创建重复项以及其中没有任何模板的元素。我只是想知道有没有其他方法。
下面还提到了输出 XML 示例:
<?xml version="1.0" encoding="utf-8"?>
<Hierarchy>
<Board>
<Name>Audi</Name>
<Template>LEVEL1</Template>
<Description>Car brand</Description>
<Board>
<Name>Transmission</Name>
<Template>LEVEL2</Template>
<Description>Part of Car</Description>
<Board>
<Name>Shift</Name>
<Template>LEVEL3</Template>
<Description>Part of Transmission</Description>
</Board>
</Board>
</Board>
<Board>
<Name>Ferrari</Name>
<Template>LEVEL1</Template>
<Description>Car brand</Description>
<Board>
<Name>Transmission</Name>
<Template>LEVEL2</Template>
<Description>Part of Car</Description>
<Board>
<Name>Shift</Name>
<Template>LEVEL3</Template>
<Description>Part of Transmission</Description>
</Board>
</Board>
</Board>
</Hierarchy>
【问题讨论】:
-
请发布minimal reproducible example 显示示例输入(作为 XML 代码)、预期输出(也作为代码)和您当前的尝试。 -- 提示:如果你只传递在
descendant-or-self轴上具有“Shift”的节点,这将相当简单。 -
我喜欢这个问题。本质上,您希望找到具有指定数据值的节点。然后你想得到那个节点,以及它的所有祖先(即父母、祖父母、曾祖父母等)。所以,这是一种方法:找到指定的数据点。使用祖先或自我轴创建一个节点集,然后以正确的顺序输出节点集...如果您需要更多帮助,请按照迈克尔上面的建议修改您的问题...
-
@Bluewood66 您的方法将为兄弟节点创建重复的分支。
-
@michael.hor257k 例如,如果我找到“1.2.2 Shift”节点,则获取其父节点“1.2 Transmission”,然后获取其祖父节点“1. Audi”。那会奏效。同样,如果获得“2.2.2 Shift”,则父“2.2 Transmission”的祖父“2. Ferrari”也可以使用。所以,只要我从带有“Shift”的子节点开始,我可能就很好。该方法是自下而上,而不是自上而下......但是,请让我知道如何创建重复的分支。我认为自上而下的方法会有更多问题。
-
@Bluewood66 我会在 OP 发布他的 XML 代码时澄清这一点 - 但请考虑如果制造商有两个部门会发生什么。你的结果的根元素是什么。