数据类型映射:使用 "for-each" 查询数组值
Datatype map: Query array values using "for-each"
我想从一个数组中提取值,其中每个数组都连接到一个对象键名。
我遇到的问题是不知道如何将内部“xsl:foreach”构造成映射数组。
稍后我将通过添加属性来区分元素,但我将其省略以将问题和数据保持在最低水平。
JSON:
<data>
{
"datasheets": {
"balance": {
"cash": [4, 2, 3, 1],
"bank": [5, 8, 7, 9]
}
}
}
</data>
XSL:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:docroot="http://www.example.org/1"
xmlns:report="http://www.example.org/2"
xmlns:cells="http://www.example.org/3"
expand-text="yes"
>
<xsl:output method="xml" indent="yes"/>
<xsl:mode on-no-match="shallow-skip"/>
<!-- Parse JSON to XML -->
<xsl:template match="data">
<docroot>
<xsl:apply-templates select="json-to-xml(.)/*"/>
</docroot>
</xsl:template>
<!-- Transform balance data -->
<xsl:template match="*[@key = 'balance']">
<report:yearly-values>
<xsl:for-each select="./*">
<!-- <xsl:for-each select="./*"> -->
<xsl:element name="cells:{@key}">Placeholder</xsl:element>
<!-- </xsl:for-each> -->
</xsl:for-each>
</report:yearly-values>
</xsl:template>
</xsl:transform>
结果:
<?xml version="1.0" encoding="UTF-8"?>
<docroot xmlns:cells="http://www.example.org/3"
xmlns:docroot="http://www.example.org/1"
xmlns:report="http://www.example.org/2">
<report:yearly-values>
<cells:cash>Placeholder</cells:cash>
<cells:bank>Placeholder</cells:bank>
</report:yearly-values>
</docroot>
想要的结果:
<?xml version="1.0" encoding="UTF-8"?>
<docroot xmlns:cells="http://www.example.org/3"
xmlns:docroot="http://www.example.org/1"
xmlns:report="http://www.example.org/2">
<report:yearly-values>
<cells:cash>4</cells:cash>
<cells:cash>2</cells:cash>
<cells:cash>3</cells:cash>
<cells:cash>1</cells:cash>
<cells:bank>5</cells:bank>
<cells:bank>8</cells:bank>
<cells:bank>7</cells:bank>
<cells:bank>9</cells:bank>
</report:yearly-values>
</docroot>
您只是在遍历两个数组,而不是数组的内容。以下将产生所需的输出:
<xsl:for-each select="./*/*">
<!-- <xsl:for-each select="./*/*"> -->
<xsl:element name="cells:{parent::*/@key}">
<xsl:value-of select="."/>
</xsl:element>
<!-- </xsl:for-each> -->
</xsl:for-each>
当您第一次执行此调试步骤以查看发生了什么时:
<xsl:template match="*[@key = 'balance']">
<report:yearly-values>
<xsl:copy-of select="."/>
</report:yearly-values>
</xsl:template>
会给这个xml片段:
<report:yearly-values>
<map xmlns="http://www.w3.org/2005/xpath-functions" key="balance">
<array key="cash">
<number>4</number>
<number>2</number>
<number>3</number>
<number>1</number>
</array>
<array key="bank">
<number>5</number>
<number>8</number>
<number>7</number>
<number>9</number>
</array>
</map>
</report:yearly-values>
那就更清楚你需要什么了。将 for-each 更深一层,并为您的元素名称使用父级的 @key,如下所示:
<xsl:template match="*[@key = 'balance']">
<report:yearly-values>
<xsl:for-each select="*/*">
<xsl:element name="cells:{parent::*/@key}"><xsl:value-of select="text()"/></xsl:element>
</xsl:for-each>
</report:yearly-values>
</xsl:template>
我想从一个数组中提取值,其中每个数组都连接到一个对象键名。 我遇到的问题是不知道如何将内部“xsl:foreach”构造成映射数组。
稍后我将通过添加属性来区分元素,但我将其省略以将问题和数据保持在最低水平。
JSON:
<data>
{
"datasheets": {
"balance": {
"cash": [4, 2, 3, 1],
"bank": [5, 8, 7, 9]
}
}
}
</data>
XSL:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:docroot="http://www.example.org/1"
xmlns:report="http://www.example.org/2"
xmlns:cells="http://www.example.org/3"
expand-text="yes"
>
<xsl:output method="xml" indent="yes"/>
<xsl:mode on-no-match="shallow-skip"/>
<!-- Parse JSON to XML -->
<xsl:template match="data">
<docroot>
<xsl:apply-templates select="json-to-xml(.)/*"/>
</docroot>
</xsl:template>
<!-- Transform balance data -->
<xsl:template match="*[@key = 'balance']">
<report:yearly-values>
<xsl:for-each select="./*">
<!-- <xsl:for-each select="./*"> -->
<xsl:element name="cells:{@key}">Placeholder</xsl:element>
<!-- </xsl:for-each> -->
</xsl:for-each>
</report:yearly-values>
</xsl:template>
</xsl:transform>
结果:
<?xml version="1.0" encoding="UTF-8"?>
<docroot xmlns:cells="http://www.example.org/3"
xmlns:docroot="http://www.example.org/1"
xmlns:report="http://www.example.org/2">
<report:yearly-values>
<cells:cash>Placeholder</cells:cash>
<cells:bank>Placeholder</cells:bank>
</report:yearly-values>
</docroot>
想要的结果:
<?xml version="1.0" encoding="UTF-8"?>
<docroot xmlns:cells="http://www.example.org/3"
xmlns:docroot="http://www.example.org/1"
xmlns:report="http://www.example.org/2">
<report:yearly-values>
<cells:cash>4</cells:cash>
<cells:cash>2</cells:cash>
<cells:cash>3</cells:cash>
<cells:cash>1</cells:cash>
<cells:bank>5</cells:bank>
<cells:bank>8</cells:bank>
<cells:bank>7</cells:bank>
<cells:bank>9</cells:bank>
</report:yearly-values>
</docroot>
您只是在遍历两个数组,而不是数组的内容。以下将产生所需的输出:
<xsl:for-each select="./*/*">
<!-- <xsl:for-each select="./*/*"> -->
<xsl:element name="cells:{parent::*/@key}">
<xsl:value-of select="."/>
</xsl:element>
<!-- </xsl:for-each> -->
</xsl:for-each>
当您第一次执行此调试步骤以查看发生了什么时:
<xsl:template match="*[@key = 'balance']">
<report:yearly-values>
<xsl:copy-of select="."/>
</report:yearly-values>
</xsl:template>
会给这个xml片段:
<report:yearly-values>
<map xmlns="http://www.w3.org/2005/xpath-functions" key="balance">
<array key="cash">
<number>4</number>
<number>2</number>
<number>3</number>
<number>1</number>
</array>
<array key="bank">
<number>5</number>
<number>8</number>
<number>7</number>
<number>9</number>
</array>
</map>
</report:yearly-values>
那就更清楚你需要什么了。将 for-each 更深一层,并为您的元素名称使用父级的 @key,如下所示:
<xsl:template match="*[@key = 'balance']">
<report:yearly-values>
<xsl:for-each select="*/*">
<xsl:element name="cells:{parent::*/@key}"><xsl:value-of select="text()"/></xsl:element>
</xsl:for-each>
</report:yearly-values>
</xsl:template>