我想询问如何通过 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>
外部循环仅处理 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>