【问题标题】:Datatype map: Query array values using "for-each"数据类型映射:使用“for-each”查询数组值
【发布时间】:2021-08-12 11:32:34
【问题描述】:

我希望从一个数组中提取值,其中每个数组都连接到一个对象键名。 我遇到的问题是不知道如何将内部“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>

【问题讨论】:

    标签: json xml xslt xslt-3.0


    【解决方案1】:

    当您第一次执行此调试步骤以查看发生了什么时:

      <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>
    

    【讨论】:

      【解决方案2】:

      您只是在迭代两个数组,而不是数组的内容。以下将产生所需的输出:

      <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>
      

      【讨论】:

        猜你喜欢
        • 2021-08-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多