恢复并说明隐藏在属性数据中的父/母之间的互连(并且未以XML表示为结构)[XSLT 1.0]

时间:2019-12-22 19:56:47

标签: xml xslt

XML文件由绝对同类的节点序列组成。遵循xml形式逻辑-没有父子互连。所有节点都在同一级别,它们是同级节点。所有节点包括:

  • 具有相同名称的单个元素,由
  • 组成
  • 相同的属性集

所以它的结构总是像这样:

<document ID-1="value" ID-2="value" ID-3="value" attr-4="value"/>
<document ID-1="value" ID-2="value" ID-3="value" attr-4="value"/>
<document ID-1="value" ID-2="value" ID-3="value" attr-4="value"/>
<document ID-1="value" ID-2="value" ID-3="value" attr-4="value"/>
...etc

但是。尽管具有同质性,但实际上,在属性“值”中包含的数据级别上,存在有关层次结构的信息,因此需要对其进行说明。条件模型的虚拟层次结构:

  
      
  • 父母      
        
    • 亚父母      
          
      • 孩子
      •   
    •   
  •   
     

根据以下方案建立连接:

     
      
  • 孩子的ID-2 =“ value”等于父级ID-1 =“ value”
  •   
  • 父级ID-2 =“ value”等于父级ID-1 =“ value”

         

    PICTURE

  • 中的完整可视化方案   

目标: 恢复每个节点中的所有层次结构链信息。从技术上讲-向所有下级元素(子级,下级父级)添加具有所有“上层”元素的值的属性。在建议的模型中,这意味着从相应的父节点和/或子父节点添加(复制) attr-4 =“值” 。简单地说,这意味着应在子元素中添加两个 attr-4 =“ value” (来自父级和父级)。

1-来源:

<document ID-1="SunID"   ID-2="NULL"  ID-3="value" attr-4="SUN"/>      <!-- this is parent's node -->
<document ID-1="EarthID" ID-2="SunID" ID-3="value" attr-4="EARTH" />   <!-- this is subparent -->

<document ID-1="value" ID-2="EarthID" ID-3="value" attr-4="Tokio"/>     <!-- child-1 -->
<document ID-1="value" ID-2="EarthID" ID-3="value" attr-4="London"/>    <!-- child-2 -->
<document ID-1="value" ID-2="EarthID" ID-3="value" attr-4="Rome"/>      <!-- child-3 -->
<document ID-1="value" ID-2="EarthID" ID-3="value" attr-4="Cairo"/>     <!-- child-4 -->

2-XSLT解决方案

我可以假设可以在XSLT中实现的算法的以下几点:

  • 匹配文档节点
  • 节点的自我复制
  • 通过XML文件搜索表达式,其中(孩子的ID-2)=(子父母的ID-1)
  • 通过XML文件搜索表达式,其中(子父母的ID-2)=(父母的ID-1)
  • 因此,在找到所有层次结构的ID链后,我们可以为节点明确显示所需的模型

(注意)对于这些表达式可能有用的信息:ID-3值是所有xml文件中真正唯一的ID。

3-OUTPUT(相关型号)

<document ID-1="SunID"   ID-2="NULL"  ID-3="value" attr-4="SUN"/>                <!-- this is parent's date -->
<document ID-1="EarthID" ID-2="SunID" ID-3="value" attr-4="EARTH" attr-5="SUN"/> <!-- this is subparent -->

<document ID-1="value" ID-2="EarthID" ID-3="value" attr-4="Tokio"  attr-5="EARTH" attr-6="SUN" />  <!-- child-1 -->
<document ID-1="value" ID-2="EarthID" ID-3="value" attr-4="London" attr-5="EARTH" attr-6="SUN" />  <!-- child-2 -->
<document ID-1="value" ID-2="EarthID" ID-3="value" attr-4="Rome"   attr-5="EARTH" attr-6="SUN" />  <!-- child-3 -->
<document ID-1="value" ID-2="EarthID" ID-3="value" attr-4="Cairo"  attr-5="EARTH" attr-6="SUN" />  <!-- child-4 -->

主要问题:XSLT代码看起来如何? [更新:在XSLT 1.0中的说明]

(请注意)-当然,我们事先并不确切知道父,子或子节点的位置。以及其属性值的内容。所有这些EARTH,SUN值都必须动态计算。

1 个答案:

答案 0 :(得分:1)

即使在XSLT 1中,您也具有定义和遵循任何引用的键,它只是使用apply-templates函数找到的元素的递归key

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

<xsl:template match="@* | node()">
    <xsl:copy>
        <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
</xsl:template>

<xsl:key name="ref" match="document" use="@ID-1"/>

<xsl:template match="document">
    <xsl:copy>
        <xsl:copy-of select="@*"/>
        <xsl:apply-templates select="key('ref', @ID-2)" mode="att"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="document" mode="att">
    <xsl:param name="pos" select="count(@*) + 1"/>
    <xsl:attribute name="attr-{$pos}">
        <xsl:value-of select="@attr-4"/>
    </xsl:attribute>
    <xsl:apply-templates select="key('ref', @ID-2)" mode="att">
        <xsl:with-param name="pos" select="$pos + 1"/>
    </xsl:apply-templates>
</xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/ncntCSJ/1