如何在兄弟节点之前移动节点并为其提供与父节点相关的属性?

时间:2017-12-22 13:37:23

标签: xslt xslt-1.0

我有以下文档结构:

<?xml version="1.0"?>
<catalog>
  <navigationRoot>
    <!-- more elements-->
    <navigation id="123" type="level0">
      <!-- more elements-->
      <navigationNodes>
        <navigationNode>
          <!-- more elements-->
        </navigationNode>
        <navigationNode>
          <!-- more elements-->
        </navigationNode>
        <!--...-->
      </navigationNodes>
      <children>
        <navigation idref="196439"/>
        <navigation idref="196459"/>
        <!--...-->
      </children>
      <!-- more elements-->
    </navigation>
    <navigation id="196439" type="level1">
      <!-- more elements-->
      <navigationNodes>
        <navigationNode>
          <!-- more elements-->
        </navigationNode>
        <navigationNode>
          <!-- more elements-->
        </navigationNode>
        <!--...-->
      </navigationNodes>
      <children>
        <navigation idref="19643261"/>
        <navigation idref="196463463"/>
        <!--...-->
      </children>
      <!-- more elements-->
    </navigation>   
    <navigation id="196459" type="level1">
      <!-- more elements-->
      <navigationNodes>
        <navigationNode>
          <!-- more elements-->
        </navigationNode>
        <navigationNode>
          <!-- more elements-->
        </navigationNode>
        <!--...-->
      </navigationNodes>
      <children>
        <navigation idref="19644361"/>
        <navigation idref="19643467"/>
        <!--...-->
      </children>
      <!-- more elements-->
    </navigation>       
  </navigationRoot>
</catalog>

我需要移动孩子&#34; &#34; navigationNodes&#34;之前的元素&#34;导航中的元素id = ...&#34;元素。进一步,我必须给&#34;导航idref = ...&#34;元素另一个属性&#34; type&#34;等于父元素的++级。例如,在本文档中,在&#34;导航id = 123&#34;节点子节点应放在&#34; navigationNode&#34;元素并且具有&#34; level1&#34;的类型,如下所示:

   <navigation id="123" type="level0">
      <!-- more elements-->
      <children>
        <navigation idref="196439" type="level1"/>
        <navigation idref="196459" type="level1"/>
        <!--...-->
      </children>
      <navigationNodes>
        <navigationNode>
          <!-- more elements-->
        </navigationNode>
        <navigationNode>
          <!-- more elements-->
        </navigationNode>
        <!--...-->
      </navigationNodes>
      <!-- more elements-->
    </navigation>

我如何实现这一目标?

1 个答案:

答案 0 :(得分:2)

四个步骤:

  1. 身份转换。
  2. 设计模板以在@type上插入新的children/navigation。在此解决方案中,仅当@id中给出@idref的任何元素存在时才添加该属性(您可以考虑使用xml:id而只使用id())。您也可以将其缩小到navigation
  3. 然后,在匹配children时,复制它,应用children/navigation,并附加以下任何navigationNodes。因此children实际上会在navigation之前“移动”children。我天真地认为每个navigation中只有一个navigationNodes
  4. 最后,忽略已在步骤3中复制的所有<xsl:template match="node() | @*"> <xsl:copy> <xsl:apply-templates select="node() | @*"/> </xsl:copy> </xsl:template> <xsl:template match="children/navigation[@idref]"> <xsl:variable name="type" select="//*[@id = current()/@idref]/@type"/> <xsl:copy> <xsl:if test="$type"> <xsl:attribute name="type"> <xsl:value-of select="$type"/> </xsl:attribute> </xsl:if> <xsl:apply-templates select="node() | @*"/> </xsl:copy> </xsl:template> <xsl:template match="children"> <xsl:copy> <xsl:apply-templates select="node() | @*"/> </xsl:copy> <xsl:copy-of select="preceding-sibling::navigationNodes"/> </xsl:template> <xsl:template match="navigationNodes"/>
  5.     

    tabLayout.setVisibility(View.GONE);
    

    完成!希望这会有所帮助。