当条目中存在属性时,我需要隐藏元素。当存在属性cols时,其余的空条目应隐藏在同一行中。当存在属性morerows时,应删除存在于同一列的下一行中的条目。
示例输入:
<?xml version="1.0"?>
<table>
<tbody>
<row>
<entry cols="2">Row 1 Col 1</entry>
<entry></entry>
<entry></entry>
<entry morerows="2">Row 1 Col 4</entry>
<entry>Row 1 Col 5</entry>
</row>
<row>
<entry>Row 2 Col 1</entry>
<entry>Row 2 Col 2</entry>
<entry>Row 2 Col 3</entry>
<entry></entry>
<entry>Row 2 Col 5</entry>
</row>
<row>
<entry>Row 3 Col 1</entry>
<entry>Row 3 Col 2</entry>
<entry>Row 3 Col 3</entry>
<entry></entry>
<entry>Row 3 Col 5</entry>
</row>
</tbody>
</table>
输出:
<?xml version="1.0"?>
<table>
<tbody>
<row>
<entry cols="2">Row 1 Col 1</entry>
<entry morerows="2">Row 1 Col 4</entry>
<entry>Row 1 Col 5</entry>
</row>
<row>
<entry>Row 2 Col 1</entry>
<entry>Row 2 Col 2</entry>
<entry>Row 2 Col 3</entry>
<entry>Row 2 Col 5</entry>
</row>
<row>
<entry>Row 3 Col 1</entry>
<entry>Row 3 Col 2</entry>
<entry>Row 3 Col 3</entry>
<entry>Row 3 Col 5</entry>
</row>
</tbody>
</table>
XSLT尝试过:
<?xml version='1.0'?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.w3.org/1998/Math/MathML" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:mml="http://www.w3.org/1998/Math/MathML">
<xsl:output method="xml" encoding="UTF-8" indent="no"/>
<xsl:template match="@* | node()"><xsl:copy><xsl:apply-templates select="@* | node()"/></xsl:copy></xsl:template>
<xsl:template match="row">
<xsl:copy>
<xsl:for-each select="entry">
<xsl:if test="@cols"><xsl:variable name="span_cols" select="@cols+1"/></xsl:if>
<xsl:apply-templates select="following-sibling::*[$span_cols]"/>
</xsl:for-each>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="entry">
<xsl:choose>
<xsl:when test="@cols">
<xsl:copy>
<xsl:variable name="current_colno" select="count(preceding-sibling::entry)+1"/>
<xsl:variable name="span_cols" select="@cols+1"/>
<xsl:attribute name="namest"><xsl:value-of select="$current_colno"/></xsl:attribute>
<xsl:attribute name="nameend"><xsl:value-of select="sum($span_cols,$current_colno)"/></xsl:attribute>
</xsl:copy>
</xsl:when>
<xsl:otherwise><xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy></xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet
&GT;
答案 0 :(得分:1)
我编写了一些代码,试图分三步实现转换:
entry
属性cols
个元素
entry
属性morerows
个元素
entry
元素以下是代码:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs">
<xsl:output indent="yes"/>
<xsl:template match="@* | node()" mode="#all">
<xsl:copy>
<xsl:apply-templates select="@* , node()" mode="#current"/>
</xsl:copy>
</xsl:template>
<xsl:template match="tbody">
<xsl:copy>
<xsl:variable name="cols-flagged-to-delete" as="element(tbody)">
<xsl:copy>
<xsl:apply-templates select="*" mode="flag-to-delete-col"/>
</xsl:copy>
</xsl:variable>
<xsl:variable name="rows-flagged-to-delete" as="element(row)*">
<xsl:apply-templates select="$cols-flagged-to-delete" mode="flag-to-delete-row"/>
</xsl:variable>
<xsl:apply-templates select="$rows-flagged-to-delete" mode="delete"/>
</xsl:copy>
</xsl:template>
<xsl:template match="tbody/row" mode="flag-to-delete-col">
<xsl:copy>
<xsl:for-each-group select="entry" group-starting-with="entry[@cols]">
<xsl:choose>
<xsl:when test="self::entry[@cols]">
<xsl:variable name="cols" as="xs:integer" select="xs:integer(@cols)"/>
<xsl:apply-templates select="."/>
<xsl:apply-templates select="current-group()[not(node()) and position() gt 1 and position() le (1 + $cols)]"
mode="flag-to-delete-col"/>
<xsl:apply-templates select="current-group()[position() gt (1 + $cols)]"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
<xsl:template match="tbody/row/entry" mode="flag-to-delete-col flag-to-delete-row">
<entry delete="true"/>
</xsl:template>
<xsl:template match="tbody" mode="flag-to-delete-row">
<xsl:for-each-group select="row" group-starting-with="row[entry/@morerows]">
<xsl:choose>
<xsl:when test="self::row[entry/@morerows]">
<xsl:variable name="pos" as="xs:integer" select="count(entry[@morerows]/preceding-sibling::entry) + 1"/>
<xsl:variable name="n" as="xs:integer" select="xs:integer(entry/@morerows)"/>
<xsl:apply-templates select="current-group()" mode="flag-to-delete-row">
<xsl:with-param name="pos" select="$pos"/>
<xsl:with-param name="n" select="$n"/>
</xsl:apply-templates>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:template>
<xsl:template match="tbody/row" mode="flag-to-delete-row">
<xsl:param name="pos"/>
<xsl:param name="n"/>
<xsl:copy>
<xsl:choose>
<xsl:when test="position() gt 1 and position() le (1 + $n)">
<xsl:apply-templates select="entry[position() lt $pos]"/>
<xsl:apply-templates select="entry[$pos]" mode="flag-to-delete-row"/>
<xsl:apply-templates select="entry[position() gt $pos]"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="entry"/>
</xsl:otherwise>
</xsl:choose>
</xsl:copy>
</xsl:template>
<xsl:template match="row/entry[@delete = 'true']" mode="delete"/>
</xsl:stylesheet>
但是我只测试了你提供的小样本,所以当我使用Saxon 9.5进行转换时
<?xml version="1.0"?>
<table>
<tbody>
<row>
<entry cols="2">Row 1 Col 1</entry>
<entry></entry>
<entry></entry>
<entry morerows="2">Row 1 Col 4</entry>
<entry>Row 1 Col 5</entry>
</row>
<row>
<entry>Row 2 Col 1</entry>
<entry>Row 2 Col 2</entry>
<entry>Row 2 Col 3</entry>
<entry></entry>
<entry>Row 2 Col 5</entry>
</row>
<row>
<entry>Row 3 Col 1</entry>
<entry>Row 3 Col 2</entry>
<entry>Row 3 Col 3</entry>
<entry></entry>
<entry>Row 3 Col 5</entry>
</row>
</tbody>
</table>
我确实得到了
<table>
<tbody>
<row>
<entry cols="2">Row 1 Col 1</entry>
<entry morerows="2">Row 1 Col 4</entry>
<entry>Row 1 Col 5</entry>
</row>
<row>
<entry>Row 2 Col 1</entry>
<entry>Row 2 Col 2</entry>
<entry>Row 2 Col 3</entry>
<entry>Row 2 Col 5</entry>
</row>
<row>
<entry>Row 3 Col 1</entry>
<entry>Row 3 Col 2</entry>
<entry>Row 3 Col 3</entry>
<entry>Row 3 Col 5</entry>
</row>
</tbody>
</table>
但我认为需要更复杂的输入和输出样本来测试代码,所以请这样做并报告回来。我假设每个morerows
元素的entry
元素中只有一个row
属性,我不确定这个假设适用于您的输入要求。