foreach 期间 "position()" 中数字增加的断点
Breakpoint of number increase in "position()" during foreach
我在“foreach”期间增加了一个属性值中的数字。由于名称为“product-1”、“product-2”等的每个键的数组有 4 个值,我需要将数字增加到仅从 0 到 3,然后从 0 到 3 重复,直到处理对象结束。
我的原始 JSON 数据包含更多产品。产品的数量未知,并且可能会不时发生变化。我将 JSON 数据最小化以更好地适应问题。
除了属性文本值从 0 增加到 6 之外,所有代码都工作正常。
问题:
如何调整代码,使属性文本值的数量从 0 增加到 3,然后作为“foreach”的一部分重复。
JSON数据:
<data>
{
"store": {
"product-1": [0, 3, 2, 1],
"product-2": [4, 7, 6, 5]
},
"other": {
"Xxx": 42
}
}
</data>
XSL:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:item="http://www.example.org/1"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
exclude-result-prefixes="fn"
expand-text="yes"
>
<xsl:output method="xml" indent="yes"/>
<xsl:mode on-no-match="shallow-skip"/>
<!-- Parse JSON to XML -->
<xsl:template match="data">
<inventory>
<xsl:apply-templates select="json-to-xml(.)/*"/>
</inventory>
</xsl:template>
<!-- Attribute setting -->
<xsl:attribute-set name="datasheet-result">
<xsl:attribute name="unitRef">USD</xsl:attribute>
</xsl:attribute-set>
<!-- Template -->
<xsl:template match="*[@key = 'store']">
<xsl:for-each select="*/*">
<xsl:element name="item:{parent::*/@key}" use-attribute-sets="datasheet-result">
<xsl:attribute name="contextRef">period{position() - 1}</xsl:attribute>
<xsl:value-of select="text()"/>
</xsl:element>
</xsl:for-each>
</xsl:template>
</xsl:transform>
结果:
<?xml version="1.0" encoding="UTF-8"?>
<inventory xmlns:item="http://www.example.org/1">
<item:product-1 unitRef="USD" contextRef="period0">0</item:product-1>
<item:product-1 unitRef="USD" contextRef="period1">3</item:product-1>
<item:product-1 unitRef="USD" contextRef="period2">2</item:product-1>
<item:product-1 unitRef="USD" contextRef="period3">1</item:product-1>
<item:product-2 unitRef="USD" contextRef="period4">4</item:product-2>
<item:product-2 unitRef="USD" contextRef="period5">7</item:product-2>
<item:product-2 unitRef="USD" contextRef="period6">6</item:product-2>
<item:product-2 unitRef="USD" contextRef="period7">5</item:product-2>
</inventory>
想要的结果:
<?xml version="1.0" encoding="UTF-8"?>
<inventory xmlns:item="http://www.example.org/1">
<item:product-1 unitRef="USD" contextRef="period0">0</item:product-1>
<item:product-1 unitRef="USD" contextRef="period1">3</item:product-1>
<item:product-1 unitRef="USD" contextRef="period2">2</item:product-1>
<item:product-1 unitRef="USD" contextRef="period3">1</item:product-1>
<item:product-2 unitRef="USD" contextRef="period0">4</item:product-2>
<item:product-2 unitRef="USD" contextRef="period1">7</item:product-2>
<item:product-2 unitRef="USD" contextRef="period2">6</item:product-2>
<item:product-2 unitRef="USD" contextRef="period3">5</item:product-2>
</inventory>
像这样使用xsl:for-每次2次:
<xsl:template match="*[@key = 'store']">
<xsl:for-each select="*">
<xsl:for-each select="*">
<xsl:element name="item:{parent::*/@key}" use-attribute-sets="datasheet-result">
<xsl:attribute name="contextRef">period{position() - 1}</xsl:attribute>
<xsl:value-of select="text()"/>
</xsl:element>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
Siebe 为您提供了一个使用两个嵌套 for-each
的示例,以便 position()
匹配您想要的结果,另一种选择是使用 xsl:number
,例如<xsl:attribute name="contextRef">period<xsl:number start-at="0"/></xsl:attribute>
是最短的例子。
至于 xsl:number
的工作原理,最短的 <xsl:number/>
基本上将相同“类型”的兄弟节点计算为上下文节点,并输出该数字加一。通常有多种使用它的选项,请参阅 XSLT 的任何介绍,例如 https://cranesoftwrights.github.io/books/ptux/index.htm 可以免费下载 XSLT 2 和 1 介绍的 PDF 副本(“使用 XSLT 和 XPath 的实用转换”)和在第 8 章“构建结果树”中有第 3 节“编号说明”/“源树编号”。
当然可以随意浏览规格部分 https://www.w3.org/TR/xslt-30/#number。
我在“foreach”期间增加了一个属性值中的数字。由于名称为“product-1”、“product-2”等的每个键的数组有 4 个值,我需要将数字增加到仅从 0 到 3,然后从 0 到 3 重复,直到处理对象结束。
我的原始 JSON 数据包含更多产品。产品的数量未知,并且可能会不时发生变化。我将 JSON 数据最小化以更好地适应问题。
除了属性文本值从 0 增加到 6 之外,所有代码都工作正常。
问题:
如何调整代码,使属性文本值的数量从 0 增加到 3,然后作为“foreach”的一部分重复。
JSON数据:
<data>
{
"store": {
"product-1": [0, 3, 2, 1],
"product-2": [4, 7, 6, 5]
},
"other": {
"Xxx": 42
}
}
</data>
XSL:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:item="http://www.example.org/1"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
exclude-result-prefixes="fn"
expand-text="yes"
>
<xsl:output method="xml" indent="yes"/>
<xsl:mode on-no-match="shallow-skip"/>
<!-- Parse JSON to XML -->
<xsl:template match="data">
<inventory>
<xsl:apply-templates select="json-to-xml(.)/*"/>
</inventory>
</xsl:template>
<!-- Attribute setting -->
<xsl:attribute-set name="datasheet-result">
<xsl:attribute name="unitRef">USD</xsl:attribute>
</xsl:attribute-set>
<!-- Template -->
<xsl:template match="*[@key = 'store']">
<xsl:for-each select="*/*">
<xsl:element name="item:{parent::*/@key}" use-attribute-sets="datasheet-result">
<xsl:attribute name="contextRef">period{position() - 1}</xsl:attribute>
<xsl:value-of select="text()"/>
</xsl:element>
</xsl:for-each>
</xsl:template>
</xsl:transform>
结果:
<?xml version="1.0" encoding="UTF-8"?>
<inventory xmlns:item="http://www.example.org/1">
<item:product-1 unitRef="USD" contextRef="period0">0</item:product-1>
<item:product-1 unitRef="USD" contextRef="period1">3</item:product-1>
<item:product-1 unitRef="USD" contextRef="period2">2</item:product-1>
<item:product-1 unitRef="USD" contextRef="period3">1</item:product-1>
<item:product-2 unitRef="USD" contextRef="period4">4</item:product-2>
<item:product-2 unitRef="USD" contextRef="period5">7</item:product-2>
<item:product-2 unitRef="USD" contextRef="period6">6</item:product-2>
<item:product-2 unitRef="USD" contextRef="period7">5</item:product-2>
</inventory>
想要的结果:
<?xml version="1.0" encoding="UTF-8"?>
<inventory xmlns:item="http://www.example.org/1">
<item:product-1 unitRef="USD" contextRef="period0">0</item:product-1>
<item:product-1 unitRef="USD" contextRef="period1">3</item:product-1>
<item:product-1 unitRef="USD" contextRef="period2">2</item:product-1>
<item:product-1 unitRef="USD" contextRef="period3">1</item:product-1>
<item:product-2 unitRef="USD" contextRef="period0">4</item:product-2>
<item:product-2 unitRef="USD" contextRef="period1">7</item:product-2>
<item:product-2 unitRef="USD" contextRef="period2">6</item:product-2>
<item:product-2 unitRef="USD" contextRef="period3">5</item:product-2>
</inventory>
像这样使用xsl:for-每次2次:
<xsl:template match="*[@key = 'store']">
<xsl:for-each select="*">
<xsl:for-each select="*">
<xsl:element name="item:{parent::*/@key}" use-attribute-sets="datasheet-result">
<xsl:attribute name="contextRef">period{position() - 1}</xsl:attribute>
<xsl:value-of select="text()"/>
</xsl:element>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
Siebe 为您提供了一个使用两个嵌套 for-each
的示例,以便 position()
匹配您想要的结果,另一种选择是使用 xsl:number
,例如<xsl:attribute name="contextRef">period<xsl:number start-at="0"/></xsl:attribute>
是最短的例子。
至于 xsl:number
的工作原理,最短的 <xsl:number/>
基本上将相同“类型”的兄弟节点计算为上下文节点,并输出该数字加一。通常有多种使用它的选项,请参阅 XSLT 的任何介绍,例如 https://cranesoftwrights.github.io/books/ptux/index.htm 可以免费下载 XSLT 2 和 1 介绍的 PDF 副本(“使用 XSLT 和 XPath 的实用转换”)和在第 8 章“构建结果树”中有第 3 节“编号说明”/“源树编号”。
当然可以随意浏览规格部分 https://www.w3.org/TR/xslt-30/#number。