Xml XSLT 2.0:将位置作为模板参数传递时出现项类型错误

Xml XSLT 2.0:将位置作为模板参数传递时出现项类型错误,xml,xslt,xslt-2.0,Xml,Xslt,Xslt 2.0,我一直在努力尽可能地简化代码。由于XML的性质,我不能共享原始数据,我不得不将代码清理到让我头疼的片段。我不想为每个月创建一个离散的行,我只想调用相同的代码12次。这节省了空间(在20k+行中,我需要所有我可以使用的空间),并且当代码需要调整时(最近似乎每季度发生一次),它还简化了事情。但是,当我使用以下命令时,我会得到错误: XPTY0020:子轴的上下文项的必需项类型为 节点() 我已经搜索并发现了几个有这个错误的问题,但是答案没有意义。我认为问题在于具有原子值的上下文节点。对于某些人来

我一直在努力尽可能地简化代码。由于XML的性质,我不能共享原始数据,我不得不将代码清理到让我头疼的片段。我不想为每个月创建一个离散的行,我只想调用相同的代码12次。这节省了空间(在20k+行中,我需要所有我可以使用的空间),并且当代码需要调整时(最近似乎每季度发生一次),它还简化了事情。但是,当我使用以下命令时,我会得到错误:

XPTY0020:子轴的上下文项的必需项类型为 节点()


我已经搜索并发现了几个有这个错误的问题,但是答案没有意义。我认为问题在于具有原子值的上下文节点。对于某些人来说,解决方案似乎是声明一个上下文变量。但是,我不知道为什么我需要它,因为我在一个for-each中,它为模板提供上下文,并在被调用的模板中提供值。至少,如果我没有将position()作为参数传递,它会这样做

我已经将for each x-to-y用于其他函数,但这是我第一次将位置作为模板的参数传递

任何关于如何简化我的代码片段的想法都会很好。我就是想不出如何克服这个错误

编辑:

这个片段不是一个好例子。很抱歉我需要这个在SpreadsheetML下工作,在那里我为每个月创建一个单元格。所以它看起来更像下面,显然前面有很多样式之类的代码:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
        <xsl:for-each select="contracts/ES_CMContract">
            <xsl:for-each select="1 to 12">
                <Cell ss:StyleID="s87">
                    <!-- Monthly Payments -->
                    <Data ss:Type="Number">
                        <xsl:call-template name="monthPayments">
                            <xsl:with-param name="month" select="position()"/>
                        </xsl:call-template>
                    </Data>
                </Cell>
            </xsl:for-each>
        </xsl:for-each>
    </xsl:template>
    <xsl:template name="monthPayments">
        <xsl:param name="month"/>
        <!-- Month is the position of the for-each loop from 1 to 12 -->
        <xsl:value-of select="payments/ES_CM2Payment[plannedPaymentDate/ESP_DATE/@month = $month]/amount/ES_COSTOBJECT/co_costprice/ESP_COSTPRICE/@anglosaxon_amount"/>
    </xsl:template>
</xsl:stylesheet>

您只需使用

<xsl:template match="/">
  <xsl:value-of select="for $month in 1 to 12 return contract/payments[plannedPaymentDate/@month = $month]/@amount"/>
</xsl:template>

甚至

<xsl:template match="/">
  <xsl:value-of select="contract/payments[plannedPaymentDate/@month = (1 to 12)]/@amount"/>
</xsl:template>

尽管这可能会给出不同的值顺序

至于需要为每个数字创建一个XML元素,请使用

<xsl:template match="/">
    <xsl:for-each select="contracts/ES_CMContract">
        <xsl:variable name="contract" select="."/>
        <xsl:for-each select="1 to 12">
            <Cell ss:StyleID="s87">
                <!-- Monthly Payments -->
                <Data ss:Type="String">
                    <xsl:value-of select="$contract/payments/ES_CM2Payment[plannedPaymentDate/ESP_DATE/@month = current()]/amount/ES_COSTOBJECT/co_costprice/ESP_COSTPRICE/@anglosaxon_amount"/>
                </Data>
            </Cell>
        </xsl:for-each>
    </xsl:for-each>
</xsl:template>


如果您真的需要调用模板,那么请确保将我显示的外部变量作为第二个参数传递。

它在我的原始代码段中工作得非常好,但我将其隔开,没有声明(或声明并删除了该段落)这是嵌入在SpreadsheetML中的,我每个月都需要一个单元格。我希望我是在XML中工作!!!伟大的这就解决了问题。不过是为了我自己的教育。为什么需要变量?我想既然我已经在合同节点中了,我就不需要再次声明我来自该节点。外部的
xsl:for each select=“contracts/ES_CMContract”
当然会使当前上下文项成为
ES_CMContract
元素,但在内部的
xsl:for each select=“1到12”
然后,上下文项是一个整数、一个原子值,而不是一个节点。因此,要访问内部for each和外部for each的上下文项,我们需要一个变量。
<xsl:template match="/">
    <xsl:for-each select="contracts/ES_CMContract">
        <xsl:variable name="contract" select="."/>
        <xsl:for-each select="1 to 12">
            <Cell ss:StyleID="s87">
                <!-- Monthly Payments -->
                <Data ss:Type="String">
                    <xsl:value-of select="$contract/payments/ES_CM2Payment[plannedPaymentDate/ESP_DATE/@month = current()]/amount/ES_COSTOBJECT/co_costprice/ESP_COSTPRICE/@anglosaxon_amount"/>
                </Data>
            </Cell>
        </xsl:for-each>
    </xsl:for-each>
</xsl:template>