使用XSLT将XML元素转换为关于现有属性的XML属性

时间:2017-11-03 12:57:12

标签: xml xslt

我有以下XML:

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

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

这导致:

<cars>
  <car brand="Volkswagen" make="Golf" wheels="4" extras=""/>
</cars>

问题:

  • 属性&#34; filter&#34;在汽车上消失了。
  • 节点的属性&#34; extras&#34;已经消失了 - 但应该在节点&#34; car&#34;。
  • 之内
  • 我不需要属性&#34; extras&#34;。

预期结果:

<cars filter="yes">
  <car brand="Volkswagen" make="Golf" wheels="4" hifi="yes" ac="no"/>
</cars>

1 个答案:

答案 0 :(得分:1)

对于第一个问题,如果缺少self.df = self.df[self.df['X'].notnull()] 属性,您可以使用身份模板而不是filter的特定模板来解决此问题

cars

对于<xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> 作为属性出现,select语句是否只能选择带有文本的元素

extra

最后,对于<xsl:for-each select="*[normalize-space()]"> 的属性,添加另一个for-each来选择它们。

extras

试试这个XSLT

  <xsl:for-each select="*/@*">
    <xsl:attribute name="{name()}">
      <xsl:value-of select="."/>
    </xsl:attribute>
  </xsl:for-each>

事实上,这两个<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

请注意,您假设<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> 的两个不同子元素没有相同的属性名称。