【问题标题】:Relink the parentID of the child of skipped element重新链接跳过元素的子元素的 parentID
【发布时间】:2021-08-01 11:43:00
【问题描述】:

我想使用 xslt 更改跳过元素的子元素的 ParentId。我的输入文件:

<?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>Employees</Name>
            <Description>Reports to the Reports to Dep Heads</Description>
            <Template>LEVEL5</Template>
        </General>
    </Board>
</Hierarchy>

预期的输出文件:

<?xml version="1.0" encoding="UTF-8"?>
<Hierarchy>
  <Board>
    <Name>President</Name>
    <Description>Top level of the Hierarchy</Description>
    <Template>LEVEL1</Template>
      <Id>ABCDE</Id>
      <ParentId></ParentId>
    <Board>
      <Name>VP</Name>
      <Description>Below the President</Description>
      <Template>LEVEL2</Template>
       <Id>EFGHI</Id>
        <ParentId>ABCDE</ParentId>
      <Board>
        <Name>Supervisors</Name>
        <Description>Reports to the Reports to Dep Heads</Description>
        <Template>LEVEL4</Template>
        <Id>OPQRS</Id>
        <ParentId>EFGHI</ParentId>
        <Board>
          <Name>Employees</Name>
          <Description>Reports to the Reports to Dep Heads</Description>
          <Template>LEVEL5</Template>
           <Id>TUVWX</Id>
        <ParentId>OPQRS</ParentId>
        </Board>
      </Board>
    </Board>
  </Board>
</Hierarchy>

现在在我提出的另一个问题的帮助下,我能够找到一种跳过元素的方法。问题链接如下: Is it possible to skip a level in a Hierarchy using XSLT?

但是,如果您在预期的输出中观察到,主管的 ParentId 更改为 VP 的 Id,因此完全跳过了元素“Depeartment Heads”。这可能吗?有人可以为此提供可能的解决方案吗?提前致谢。

【问题讨论】:

    标签: xslt xslt-1.0


    【解决方案1】:

    在将结构更改为适当的层次结构后,我不明白为什么需要 Board 元素继续携带其父级的 Id

    任何人收到以下格式的结果:

    <Hierarchy>
        <Board>
            <Name>President</Name>
            <Description>Top level of the Hierarchy</Description>
            <Template>LEVEL1</Template>
            <Id>ABCDE</Id>
            <Board>
                <Name>VP</Name>
                <Description>Below the President</Description>
                <Template>LEVEL2</Template>
                <Id>EFGHI</Id>
                <Board>
                    <Name>Supervisors</Name>
                    <Description>Reports to the Reports to Dep Heads</Description>
                    <Template>LEVEL4</Template>
                    <Id>OPQRS</Id>
                    <Board>
                        <Name>Employees</Name>
                        <Description>Reports to the Reports to Dep Heads</Description>
                        <Template>LEVEL5</Template>
                        <Id>TUVWX</Id>
                    </Board>
                </Board>
            </Board>
        </Board>
    </Hierarchy>
    

    可以很容易地看到名为SupervisorsBoard 的父级是名为VPBoard,其IdEFGHI 很容易使用表达式parent::Id 获得。在单独的 ParentId 元素中复制这个值是完全多余的。

    不过,如果你想要这种不必要的复杂性,你可以这样做:

    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:param name="parentId" select="ParentId"/>
        <xsl:copy>
            <xsl:copy-of select="General/*"/>
            <xsl:copy-of select="Id"/>
            <ParentId>
                <xsl:value-of select="$parentId"/>
            </ParentId>
            <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:with-param name="parentId" select="ParentId"/>
        </xsl:apply-templates>
    </xsl:template>
    
    </xsl:stylesheet>
    

    请注意,这是假设您不会跳过两个或多个连续级别。

    【讨论】:

    • 我很抱歉没有提到我可能不得不跳过多个元素。我这里提到的只是样本数据,但实际上有成千上万个元素,有时我不得不跳过多个级别。
    • 您可以跳过多个元素,但不能跳过父/子对。如果您可能需要这样做,则必须在所有跳过的级别中“携带”parentId 参数。
    • 您提供的解决方案是创建一个额外的“Board”层。像这样的东西:&lt;Board&gt; &lt;Board&gt; &lt;Name&gt;President&lt;/Name&gt; &lt;Description&gt;Top level of the Hierarchy&lt;/Description&gt; &lt;Template&gt;LEVEL1&lt;/Template&gt; &lt;Id&gt;ABCDE&lt;/Id&gt; &lt;/Board&gt; &lt;Board&gt; ......这里有两个板而不是一个,只有一个元素
    • 我不这么认为。您可以在此处看到它产生的正是您的问题中显示的预期输出:xsltfiddle.liberty-development.net/jxWZS7C
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-26
    • 2014-07-09
    • 1970-01-01
    相关资源
    最近更新 更多