数据类型映射:使用 "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>