xslt将文本节点转换为属性

时间:2015-12-06 20:34:40

标签: xml xslt

我制作了一个xslt脚本,该脚本将采用任何xml脚本并将元素中的文本节点转换为这些元素的属性。元素只有子元素或文本节点,但不具有属性或其他任何东西,例如

 <example>
    <A>12</A>
     <B></B>
  <example>

应该看起来像:

  <example>
    <A Val='12'></A>
    <B></B>
  <example>

这是我的脚本它基本上有两个ifs说如果元素有一个文本节点创建一个具有相同名称的新元素但是使文本成为一个属性,否则如果它不复制元素

<xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL  /Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
         <xsl:for-each select="*">
                <xsl:when test="./text()"/>
                           <xsl:element name="{local-name()}" >
                        <xsl:attribute name="Val">
                              <xsl:value-of select="normalize- space(text())"/>
                         </xsl:attribute>
                    </xsl:element>
                    </xsl:when>
                    <xsl:otherwise>
                             <xsl:copy-of select="."/>
                   </xsl:otherwise>         
             </xsl:for-each>
    </xsl:template>

xmls将比我的例子更复杂。

1 个答案:

答案 0 :(得分:2)

我没有采用xsl:for-each(拉动方法),而是使用推送方法......

XML输入

<example>
    <A>12</A>
    <A>some a text <B>some b text</B> more a text</A>
    <B></B>
</example>

XSLT 1.0

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

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

  <xsl:template match="*[text()]">
    <xsl:variable name="text">
      <xsl:apply-templates select="text()"/>
    </xsl:variable>
    <xsl:copy>
      <xsl:attribute name="Val">
        <xsl:value-of select="normalize-space($text)"/>
      </xsl:attribute>
      <xsl:apply-templates select="@*|*"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

XML输出

<example>
   <A Val="12"/>
   <A Val="some a text more a text">
      <B Val="some b text"/>
   </A>
   <B/>
</example>