通过重新安排节点使分层XML扁平化



我需要扁平化一个分层XML结构。现在,这听起来像是一个久经考验的话题,我已经倾注了很多很多的链接。但它们大多是关于从平面结构中创建层次结构的建议。

输入XML -

<bom>
    <part>
        <name>a</name>
        <othernodes>abc</othernodes>
        <part>
            <name>b</name>
            <othernodes>abc</othernodes>
            <part>
                <name>e</name>
                <othernodes>abc</othernodes>
            </part>
            <part>
                <name>f</name>
                <othernodes>abc</othernodes>
            </part>
        </part>
        <part>
            <name>c</name>
            <othernodes>abc</othernodes>
            <part>
                <name>g</name>
                <othernodes>abc</othernodes>
            </part>
        </part>
        <part>
            <name>d</name>
            <othernodes>abc</othernodes>
        </part>
    </part>
</bom>

搜索输出-

<bom>
    <part>
        <parent/>
        <name>a</name>
        <othernodes>abc</othernodes>
    </part>
    <part>
        <parent>a</parent>
        <name>b</name>
        <othernodes>abc</othernodes>
    </part>
    <part>
        <parent>a</parent>
        <name>c</name>
        <othernodes>abc</othernodes>
    </part>
    <part>
        <parent>a</parent>
        <name>d</name>
        <othernodes>abc</othernodes>
    </part>
    <part>
        <parent>b</parent>
        <name>e</name>
        <othernodes>abc</othernodes>
    </part>
    <part>
        <parent>b</parent>
        <name>f</name>
        <othernodes>abc</othernodes>
    </part>
    <part>
        <parent>c</parent>
        <name>g</name>
        <othernodes>abc</othernodes>
    </part>
</bom>

起初我认为这可能是不可能的。然后我试着想出一些xslt。我知道这里的递归是关键,但不确定如何实现。下面是我目前使用的XSLT(显然它不能产生期望的结果)。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output encoding="UTF-8" indent="yes" method="xml" />
  <xsl:template match="@* | node()">
      <xsl:copy>
          <xsl:apply-templates select="@* | node()"/>
      </xsl:copy>
  </xsl:template>
  <xsl:template match="bom">   
    <xsl:element name="bom">      
      <xsl:apply-templates select="@* | node() [not(child::part)]"/>      
      <xsl:apply-templates select="part"/>
      <!--<xsl:apply-templates select="part/child::part"/>-->
    </xsl:element>
  </xsl:template>
  <xsl:template match="part" >
    <xsl:element name="part">
      <xsl:element name="parent">
        <xsl:value-of select="../part/name"/>
      </xsl:element>
      <xsl:apply-templates select="@* | node() [not(part)]" />
      <xsl:apply-templates select="child::part"/>
    </xsl:element>    
  </xsl:template>
</xsl:stylesheet>
如果有人能就如何处理和解决这个问题提供一些指导,我将不胜感激。谢谢!

差不多完成了,样式表只需要一些固定装置(这里不需要递归):

  1. 指令<xsl:apply-templates select="@* | node() [not(child::part)]"/>应该使用self::轴,以正常工作。
  2. template match="part"中的指令必须在<xsl:element>
  3. 之外
  4. 父名称未被正确检索-使用<xsl:value-of select="../name"/>代替<xsl:value-of select="../part/name"/>
  5. 在结果树中输出任何内容之前,请考虑处理属性。

这是你的样式表的更正版本:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output encoding="UTF-8" indent="yes" method="xml" />
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="bom">
        <xsl:element name="bom">      
            <xsl:apply-templates select="@* | node()"/>      
            <!--<xsl:apply-templates select="part/child::part"/>-->
        </xsl:element>
    </xsl:template>
    <xsl:template match="part" >
        <xsl:element name="part">
            <xsl:apply-templates select="@*"/>
            <xsl:element name="parent">
                <xsl:value-of select="../name"/>
            </xsl:element>
            <xsl:apply-templates select="node() [not(self::part)]" />
        </xsl:element>    
        <xsl:apply-templates select="child::part"/>
    </xsl:template>
</xsl:stylesheet>

这是我得到的结果,与你提供的主要区别在于元素的排序方式不完全相同:

<?xml version="1.0" encoding="UTF-8"?>
<bom>
   <part>
      <parent/>
      <name>a</name>
      <othernodes>abc</othernodes>
   </part>
   <part>
      <parent>a</parent>
      <name>b</name>
      <othernodes>abc</othernodes>
   </part>
   <part>
      <parent>b</parent>
      <name>e</name>
      <othernodes>abc</othernodes>
   </part>
   <part>
      <parent>b</parent>
      <name>f</name>
      <othernodes>abc</othernodes>
   </part>
   <part>
      <parent>a</parent>
      <name>c</name>
      <othernodes>abc</othernodes>
   </part>
   <part>
      <parent>c</parent>
      <name>g</name>
      <othernodes>abc</othernodes>
   </part>
   <part>
      <parent>a</parent>
      <name>d</name>
      <othernodes>abc</othernodes>
   </part>
</bom>

相关内容

  • 没有找到相关文章

最新更新