首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在foreach中处理排除的元素

在foreach中处理排除的元素
EN

Stack Overflow用户
提问于 2021-06-01 06:23:20
回答 2查看 31关注 0票数 0

在第一个模板中,我有意排除一个元素(“牛奶”),因为解析的数据映射相对平坦,我想使用XSLT对数据进行分类和构造。目的是在第二个模板中处理被排除的元素(“牛奶”)。这两个模板一次运行一次。在一起运行模板不会显示排除的元素(“牛奶”)的结果,该元素应该设置另一个属性名和属性值。

JSON:

代码语言:javascript
复制
<data>
{
  "storage": {
    "pencils": 12,
    "milk": 8,
    "rulers": 4
  }
}
</data>

XSL:

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>

<xsl:transform
  version="3.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:storage="http://www.exammple.com/1"
  xmlns:office="http://www.exammple.com/2"
  xmlns:item="http://www.exammple.com/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">
    <storage:one>
      <xsl:apply-templates select="json-to-xml(.)"/>
    </storage:one>
  </xsl:template>

  <!-- Print map -->
  <!-- <xsl:template match="*[@key = 'storage']"> <xsl:copy-of select=".."/> </xsl:template> -->

  <xsl:template match="*[@key='storage']">

      <xsl:for-each select="*[not(@key='milk')]">
      <xsl:element name="item:{@key}">
        <xsl:attribute name="office">plant-1</xsl:attribute>
        <xsl:value-of select="text()"/>
      </xsl:element>
    </xsl:for-each>
  </xsl:template>

  <xsl:template match="*[@key='milk']">
      <xsl:for-each select=".">
      <xsl:element name="item:{@key}">
        <xsl:attribute name="beverage">plant-2</xsl:attribute>
        <xsl:value-of select="text()"/>
      </xsl:element>
    </xsl:for-each>
  </xsl:template>

</xsl:transform>

结果:

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<storage:one xmlns:item="http://www.exammple.com/3"
             xmlns:office="http://www.exammple.com/2"
             xmlns:storage="http://www.exammple.com/1">
   <item:pencils office="plant-1">12</item:pencils>
   <item:rulers office="plant-1">4</item:rulers>
</storage:one>

通缉结果:

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<storage:one xmlns:item="http://www.exammple.com/3"
             xmlns:office="http://www.exammple.com/2"
             xmlns:storage="http://www.exammple.com/1">
   <item:pencils office="plant-1">12</item:pencils>
   <item:rulers office="plant-1">4</item:rulers>
   <item:milk beverage="plant-2">8</item:milk>
</storage:one>
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-06-01 06:48:22

您的第二个模板从来没有匹配,因为它从未达到。所有元素都由<xsl:template match="*[@key='storage']">处理--它没有一个<xsl:apply-templates ...>来达到进一步的模板。

您的第一个模板不会递归到其子模板中。因此,在第一个模板的末尾添加一个<xsl:apply-templates select="*" />

代码语言:javascript
复制
    <xsl:template match="*[@key='storage']">
      <xsl:for-each select="*[not(@key='milk')]">
        <xsl:element name="item:{@key}">
          <xsl:attribute name="office">plant-1</xsl:attribute>
          <xsl:value-of select="text()"/>
        </xsl:element>
      </xsl:for-each>
      <xsl:apply-templates select="*" />
    </xsl:template>

这将尝试在“存储”级别应用进一步的模板,从而匹配第二个模板。

票数 1
EN

Stack Overflow用户

发布于 2021-06-01 06:48:15

我将为每种不同的输出类型编写模板,如果输出的顺序与xsl:sort或XPath 3.1 sort调用中的输入抛出顺序不同,则更改顺序:

代码语言:javascript
复制
  <xsl:template match="data">
    <storage:one>
      <xsl:apply-templates select="json-to-xml(.)"/>
    </storage:one>
  </xsl:template>
  
  <xsl:template match="*[@key = 'storage']">
    <xsl:apply-templates select="sort(*, (), function($el) { $el/@key = 'milk' })"/>
  </xsl:template>

  <xsl:template match="*[@key='storage']/*[not(@key='milk')]">
      <xsl:element name="item:{@key}">
        <xsl:attribute name="office">plant-1</xsl:attribute>
        <xsl:value-of select="text()"/>
      </xsl:element>
  </xsl:template>

  <xsl:template match="*[@key='storage']/*[@key='milk']">
      <xsl:element name="item:{@key}">
        <xsl:attribute name="beverage">plant-2</xsl:attribute>
        <xsl:value-of select="text()"/>
      </xsl:element>
  </xsl:template>
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67783626

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档