如何将节点移到其同级节点之前,并为其提供与父节点相关的属性?

  • 本文关键字:节点 父节点 属性 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>

我需要在"导航 id=..."元素。此外,我必须给出"导航 idref=..."元素 另一个属性"类型",等于父元素的 level++。例如,在本文档中,在"导航 id=123"节点中,子节点应放置在"navigationNode"元素上方,并且具有"level1"的类型,如下所示:

<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. 身份转换。
  2. 设计一个模板以在children/navigation上插入新@type。在此解决方案中,仅当存在具有@idref中给出的@id的任何元素时,才会添加该属性(您可以考虑xml:id并改用id())。您也可以将其缩小到navigation
  3. 然后,在匹配children上,复制它,应用children/navigation,并附加任何以下navigationNodes。所以children实际上会在navigation之前被"移动".我天真地认为每个navigation只有一个children.
  4. 最后,忽略已在步骤 3 中复制的所有navigationNodes

<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"/>

做!希望这有帮助。

相关内容

  • 没有找到相关文章