复制模板时如何重新计算位置

时间:2011-05-19 08:24:17

标签: xslt

我想问一下当我从另一个xml文件复制模板时如何重新计算行号位置和其他数据,如果满足条件,那就像在lookup.xml中那样代码。

我的程序看起来像这样:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>   
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template> 
    <xsl:template match="Line-Item[code = document('lookup.xml')/*/*/code]" />
    <xsl:template match="Line[not(Line-Item/code[not(. = document('lookup.xml')/*/*/code ) ] )]"/>  
</xsl:stylesheet>

xml文件:

<document>
    <header>
        <remarks>test</remarks>
    </header>
    <Line>
        <Line-Item>
            <lineNumb>1</lineNumb>
            <code>123</code>
            <amount>4</amount>
        </Line-Item>
        <Line-Item>
            <lineNumb>2</lineNumb>
            <code>444</code>
            <amount>2</amount>
        </Line-Item>
        <Line-Item>
            <lineNumb>3</lineNumb>
            <code>321</code>
            <amount>1</amount>
        </Line-Item>
    </Line>
    <summary>
        <total-line>3</total-line>
        <total-amount>7</total-amount>
    </summary>
</document>

Lookup.xml文件:

<lookup>
    <Codes>
        <code>123</code>
    </Codes>
</lookup>

我需要在Line-Item中重新计算lineNumb,并总结有总行数和总量。

正确的结果:

<document>
    <header>
        <remarks>test</remarks>
    </header>
    <Line>
        <Line-Item>
            <lineNumb>1</lineNumb>
            <code>444</code>
            <amount>2</amount>
        </Line-Item>
        <Line-Item>
            <lineNumb>2</lineNumb>
            <code>321</code>
            <amount>1</amount>
        </Line-Item>
    </Line>
    <summary>
        <total-line>2</total-line>
        <total-amount>3</total-amount>
    </summary>
</document>

1 个答案:

答案 0 :(得分:1)

你的工作差不多完成了。您只需要XPath count()sum()。要重新计算lineNumb,我已经计算了所有先前的兄弟元素,但是与查找代码匹配的元素。

我认为这应该可以在你的假设基础上正常工作。


Saxon-B 9.0.0.4J 上测试

XSLT 1.0

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>   

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

    <xsl:template match="Line">

        <xsl:copy>
            <xsl:apply-templates select="Line-Item"/>
        </xsl:copy>

        <xsl:variable name="lines" select="count(Line-Item[not(code = document('lookup.xml')/*/*/code)])"/>
        <xsl:variable name="amount" select="sum(Line-Item[not(code = document('lookup.xml')/*/*/code)]/amount)"/>

        <summary>
            <total-line><xsl:value-of select="$lines"/></total-line>
            <total-amount><xsl:value-of select="$amount"/></total-amount>
        </summary>
    </xsl:template>

    <xsl:template match="Line-Item">
        <xsl:copy>
            <lineNumb>
                <xsl:value-of select="count(preceding-sibling::*[not(code = document('lookup.xml')/*/*/code)])+1"/>
            </lineNumb>
            <xsl:copy-of select="code"/>
            <xsl:copy-of select="amount"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Line-Item[code = document('lookup.xml')/*/*/code]|summary" />

</xsl:stylesheet>