当许多相似节点的第一个节点出现时,我需要分配一次变量。我的最终目标是尝试从主模板中反复调用同一个模板,同时存储变量并将它们递增。xslt 1.0帮助执行第一个元素上的任务,并且处理元素上的任务不同
示例XML:
<!-- Removed See below examples -->
例XSL:
<!-- Removed See below examples -->
我会尽我所能来解释这是怎么回事: $value
是从上/ROOT
匹配的主模板引用。输出XML需要在FILE_ITEM_NBR
上有一个索引,每次创建时都是递增的。 FILE_ITEM_NBR将在循环之外生成一次,并且可以静态设置为1.其他时间生成的数据基于发票数量,在此示例中,它是每张发票3张发票的两倍。
Im使用/ROOT/INVOICES/INVOICES_ROW/INV_ID
中的文本作为我的起始数字,因为值的超过( - )部分后的数字是基于行号生成的。
我需要通过循环第一次抓住这个数字并填充$value
。任何其他时间,我需要引用该数字,为其添加一个静态数字,例如它在XSL转换中的出现次数。在示例中,我显示$value + 2
和$value + 3
。然后我需要存储该值,以便每次循环迭代时都会继续添加它。
我希望这个解释足够好。
简而言之,我需要FILE_ITEM_NBR每次在XSL转换过程中出现时唯一生成。
编辑:_______________________________________________________________________________________
我已经修改上述XML和XSL例子。以下示例运行并生成提供的输出。
示例XML:
<?xml version="1.0" encoding="UTF-8"?>
<ROOT>
<STUFF/>
<FILE_ITEM_NBR>
</FILE_ITEM_NBR>
<CLIENTNAME>TEST CLIENT</CLIENTNAME>
<INVOICES>
<INVOICES_ROW>
<INV_ID>67447-1</INV_ID>
<INV_TEST1/>
<INV_TEST2/>
<INV_TEST3/>
<MAT_NAME>BLAH BLAH BLAH 1</MAT_NAME>
<TK_ID>1</TK_ID>
<EXP_ID>3</EXP_ID>
</INVOICES_ROW>
<INVOICES_ROW>
<INV_ID>12341-2</INV_ID>
<INV_TEST1/>
<INV_TEST2/>
<INV_TEST3/>
<MAT_NAME>BLAH BLAH BLAH 2</MAT_NAME>
<TK_ID>2</TK_ID>
<EXP_ID>3</EXP_ID>
</INVOICES_ROW>
<INVOICES_ROW>
<INV_ID>142445-3</INV_ID>
<INV_TEST1/>
<INV_TEST2/>
<INV_TEST3/>
<MAT_NAME>BLAH BLAH BLAH 3</MAT_NAME>
<TK_ID>3</TK_ID>
<EXP_ID>3</EXP_ID>
</INVOICES_ROW>
</INVOICES>
</ROOT>
例XSL:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="ISO-8859-1" indent="yes"/>
<xsl:template name="INV_ID">
<xsl:choose>
<xsl:when test="boolean(.)">
<xsl:call-template name="substring-after-last">
<xsl:with-param name="input" select="normalize-space(./INV_ID)"/>
<xsl:with-param name="substr" select="'-'"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise/>
</xsl:choose>
</xsl:template>
<xsl:template name="substring-after-last">
<xsl:param name="input"/>
<xsl:param name="substr"/>
<!-- Extract the string which comes after the first occurrence -->
<xsl:variable name="temp" select="substring-after($input,$substr)"/>
<xsl:choose>
<!-- If it still contains the search string the recursively process -->
<xsl:when test="$substr and contains($temp,$substr)">
<xsl:call-template name="substring-after-last">
<xsl:with-param name="input" select="$temp"/>
<xsl:with-param name="substr" select="$substr"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$temp"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="start-get-id">
<xsl:choose>
<xsl:when test="count(preceding::INVOICES_ROW) = 0">
<!--<xsl:variable name="id">
<xsl:call-template name="INV_ID"/>
</xsl:variable>-->
<xsl:value-of select="position() * 2 "/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="position() * 2 + 2"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="/ROOT">
<root>
<stuff-to-do>
<xsl:value-of select="STUFF"/>
</stuff-to-do>
<file_item_nbr>
<xsl:text>1</xsl:text>
</file_item_nbr>
<client>
<client_name>
<xsl:value-of select="CLIENTNAME"/>
</client_name>
<file_item_nbr>
<xsl:text>2</xsl:text>
</file_item_nbr>
<xsl:for-each select="/ROOT/INVOICES/INVOICES_ROW">
<invoice>
<inv_id>
<xsl:value-of select="INV_ID"/>
</inv_id>
<inv_date>
<xsl:value-of select="INV_TEST1"/>
</inv_date>
<inv_text>
<xsl:value-of select="INV_TEST2"/>
</inv_text>
<inv_due_date>
<xsl:value-of select="INV_TEST3"/>
</inv_due_date>
<file_item_nbr>
<xsl:variable name="value">
<xsl:call-template name="start-get-id"/>
</xsl:variable>
<xsl:variable name="result">
<xsl:value-of select="$value + 1"/>
</xsl:variable>
<xsl:value-of select="$result"/>
</file_item_nbr>
<mat>
<m_name>
<xsl:value-of select="MAT_NAME"/>
</m_name>
<file_item_nbr>
<xsl:variable name="value">
<xsl:call-template name="start-get-id"/>
</xsl:variable>
<xsl:variable name="result">
<xsl:value-of select="$value + 2"/>
</xsl:variable>
<xsl:value-of select="$result"/>
</file_item_nbr>
<tksum>
<tk_id>
<xsl:value-of select="TK_ID"/>
</tk_id>
<file_item_nbr>
<xsl:variable name="value">
<xsl:call-template name="start-get-id"/>
</xsl:variable>
<xsl:variable name="result">
<xsl:value-of select="$value + 3"/>
</xsl:variable>
<xsl:value-of select="$result"/>
</file_item_nbr>
</tksum>
<expense>
<exp_id>
<xsl:value-of select="EXP_ID"/>
</exp_id>
<file_item_nbr>
<xsl:variable name="value">
<xsl:call-template name="start-get-id"/>
</xsl:variable>
<xsl:variable name="result">
<xsl:value-of select="$value + 4"/>
</xsl:variable>
<xsl:value-of select="$result"/>
</file_item_nbr>
</expense>
</mat>
</invoice>
</xsl:for-each>
</client>
</root>
</xsl:template>
</xsl:stylesheet>
生成的输出:
<?xml version="1.0" encoding="ISO-8859-1"?>
<root>
<stuff-to-do/>
<file_item_nbr>1</file_item_nbr>
<client>
<client_name>TEST CLIENT</client_name>
<file_item_nbr>2</file_item_nbr>
<invoice>
<inv_id>67447-1</inv_id>
<inv_date/>
<inv_text/>
<inv_due_date/>
<file_item_nbr>3</file_item_nbr>
<mat>
<m_name>BLAH BLAH BLAH 1</m_name>
<file_item_nbr>4</file_item_nbr>
<tksum>
<tk_id>1</tk_id>
<file_item_nbr>5</file_item_nbr>
</tksum>
<expense>
<exp_id>3</exp_id>
<file_item_nbr>6</file_item_nbr>
</expense>
</mat>
</invoice>
<invoice>
<inv_id>12341-2</inv_id>
<inv_date/>
<inv_text/>
<inv_due_date/>
<file_item_nbr>7</file_item_nbr>
<mat>
<m_name>BLAH BLAH BLAH 2</m_name>
<file_item_nbr>8</file_item_nbr>
<tksum>
<tk_id>2</tk_id>
<file_item_nbr>9</file_item_nbr>
</tksum>
<expense>
<exp_id>3</exp_id>
<file_item_nbr>10</file_item_nbr>
</expense>
</mat>
</invoice>
<invoice>
<inv_id>142445-3</inv_id>
<inv_date/>
<inv_text/>
<inv_due_date/>
<file_item_nbr>9</file_item_nbr>
<mat>
<m_name>BLAH BLAH BLAH 3</m_name>
<file_item_nbr>10</file_item_nbr>
<tksum>
<tk_id>3</tk_id>
<file_item_nbr>11</file_item_nbr>
</tksum>
<expense>
<exp_id>3</exp_id>
<file_item_nbr>12</file_item_nbr>
</expense>
</mat>
</invoice>
</client>
</root>
生成的输出是什么,我需要在我的实际情况来实现的,但是每张发票后面的数字后面加上1.
为什么你不只是编号的发票,使用任一位置()或XSL:号码,并添加1? –
只是想说什么@ michael.hor257k说...还有,这里有很多问题,其中一个是你不会生成有效的XML,因为你没有输出的根元素。另一个你开始嵌套的模板在全局变量值内调用,因为你没有上下文节点,所以start-get-id永远不会到达,否则因为count总是0,所以它转到INV_ID,其中boolean(。)将始终为true,并以空字符串作为输入调用substring-after-last。 –
所以...作为一个解决方案,我会删除除了一个匹配的ROOT之外的所有模板,并且在file_item_nbr中使用' ' –