如何对 xslt 中的位置重新编号

问题描述 投票:0回答:1

我想询问如何通过 XSLT 对 PARENTID 中的 LINENUM 和引用重新编号。 LINENUM 的顺序应该正确。目前有1,4,5,因为使用了position(),这是不正确的。如果 LINENUM 是子级并且在 PARENTID 中有参考号,则 LINENUM 可以为空。如果 LINENUM 为空,则不应按顺序计算。也可能只有父记录而没有子记录。 有简单的 xml 示例。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<data>
      <line>
         <LINENUM>1</LINENUM>
         <PARENTID/>
         <IDACTION>240730180714572</IDACTION>
      </line>
      <line>
         <LINENUM/>
         <PARENTID>1</PARENTID>
         <IDACTION></IDACTION>
      </line> 
      <line>
         <LINENUM/>
         <PARENTID>1</PARENTID>
         <IDACTION>240730180714573</IDACTION>
      </line>
      <line>
         <LINENUM>4</LINENUM>
         <PARENTID></PARENTID>
         <IDACTION>240730180714575</IDACTION>
      </line>     
      <line>
         <LINENUM>5</LINENUM>
         <PARENTID/>
         <IDACTION>240730180714578</IDACTION>
      </line>
      <line>
         <LINENUM/>
         <PARENTID>5</PARENTID>
         <IDACTION>240730180714579</IDACTION>
      </line>
      <line>
         <LINENUM/>
         <PARENTID>5</PARENTID>
         <IDACTION>2407301807145712</IDACTION>
      </line>
</data>

预期结果如下。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<data>
      <line>
         <LINENUM>1</LINENUM>
         <PARENTID/>
         <IDACTION>240730180714572</IDACTION>
      </line>
      <line>
         <LINENUM/>
         <PARENTID>1</PARENTID>
         <IDACTION></IDACTION>
      </line>
      <line>
         <LINENUM/>
         <PARENTID>1</PARENTID>
         <IDACTION>240730180714573</IDACTION>
      </line>
      <line>
         <LINENUM>2</LINENUM>
         <PARENTID></PARENTID>
         <IDACTION>240730180714575</IDACTION>
      </line>     
      <line>
         <LINENUM>3</LINENUM>
         <PARENTID/>
         <IDACTION>240730180714578</IDACTION>
      </line>
      <line>
         <LINENUM/>
         <PARENTID>3</PARENTID>
         <IDACTION>240730180714579</IDACTION>
      </line>
      <line>
         <LINENUM/>
         <PARENTID>3</PARENTID>
         <IDACTION>2407301807145712</IDACTION>
      </line>
</data>
xslt position
1个回答
0
投票

外部循环仅处理 parent

<line>
元素(那些在其
<LINENUM>
子元素中具有文本的元素),并复制它,并根据其在序列中的位置对其重新编号。然后,内部循环复制与当前父级
<line>
匹配的所有从属
<line>
元素。在这里,我使用了
xsl:key
来允许使用现有的
<line>
来查找从属
<PARENTID>
元素。

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

<xsl:output method="xml" indent="true"/>

<xsl:key name="line-by-PARENTID" match="line" use="PARENTID"/>

<xsl:template match="/data">
  <xsl:copy>
    <xsl:for-each select="line[LINENUM/text()]">
      <!-- the line's new number is its position in the 
           sequence of lines which have a LINENUM value -->
      <xsl:variable name="new-number" select="position()"/>
      <xsl:copy>
        <!-- update the LINENUM with the new number -->
        <LINENUM><xsl:value-of select="$new-number"/></LINENUM>
        <PARENTID/>
        <xsl:copy-of select="IDACTION"/>
      </xsl:copy>
      <!-- copy and renumber all the lines which have the 
           current line's LINENUM as their PARENTID value -->
      <xsl:for-each select="key('line-by-PARENTID', LINENUM)">
        <xsl:copy>
          <LINENUM/>
          <PARENTID><xsl:value-of select="$new-number"/></PARENTID>
          <xsl:copy-of select="IDACTION"/>
        </xsl:copy>
      </xsl:for-each>
    </xsl:for-each>
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>
© www.soinside.com 2019 - 2024. All rights reserved.