首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >使用XSLT将XML元素转换为尊重现有属性的XML属性

使用XSLT将XML元素转换为尊重现有属性的XML属性
EN

Stack Overflow用户
提问于 2017-11-03 04:57:12
回答 1查看 28关注 0票数 0

我有以下XML:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<cars filter="yes">
  <car>
    <brand>Volkswagen</brand>
    <make>Golf</make>
    <wheels>4</wheels>
    <extras hifi="yes" ac="no"/>
  </car>
</cars>

我想使元素<car>变平,这样它就只有属性了--不再有子元素了!

到目前为止,我已经生成了这个XSLT:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>

  <xsl:template match="cars">
    <cars>
      <xsl:apply-templates/>
    </cars>
  </xsl:template>

  <xsl:template match="car">
    <car>
      <xsl:for-each select="*">
        <xsl:attribute name="{name()}">
          <xsl:value-of select="text()"/>
        </xsl:attribute>
      </xsl:for-each>
    </car>
  </xsl:template>

</xsl:stylesheet>

这导致:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<cars>
  <car brand="Volkswagen" make="Golf" wheels="4" extras=""/>
</cars>

问题:

  • 汽车上的“过滤器”属性消失了。
  • 节点“附加”的属性已经消失,但应该在节点"car“中。
  • 我不需要附加的属性。

预期结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<cars filter="yes">
  <car brand="Volkswagen" make="Golf" wheels="4" hifi="yes" ac="no"/>
</cars>
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-11-03 05:01:12

对于第一个问题,在缺少filter属性的情况下,可以使用标识模板而不是cars的特定模板来解决这个问题。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

对于显示为属性的extra,select语句能否仅选择文本在

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<xsl:for-each select="*[normalize-space()]">

最后,对于extras的属性,添加另一个for -每个属性来获取这些属性。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  <xsl:for-each select="*/@*">
    <xsl:attribute name="{name()}">
      <xsl:value-of select="."/>
    </xsl:attribute>
  </xsl:for-each>

试试这个XSLT

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

  <xsl:template match="car">
    <car>
      <xsl:for-each select="*[normalize-space()]">
        <xsl:attribute name="{name()}">
          <xsl:value-of select="text()"/>
        </xsl:attribute>
      </xsl:for-each>
      <xsl:for-each select="*/@*">
        <xsl:attribute name="{name()}">
          <xsl:value-of select="."/>
        </xsl:attribute>
      </xsl:for-each>
    </car>
  </xsl:template>
</xsl:stylesheet>

实际上,这两个xsl:for-each语句可以在这里组合

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<xsl:template match="car">
<car>
  <xsl:for-each select="*[normalize-space()]|*/@*">
    <xsl:attribute name="{name()}">
      <xsl:value-of select="."/>
    </xsl:attribute>
  </xsl:for-each>
</car>
</xsl:template>

请注意,您假设car的两个不同的子元素没有相同的属性名。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47096363

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文