XSLT选择不匹配的元素?

时间:2012-07-05 15:45:27

标签: xml xslt

我有以下XML: -

<inventory>
  <item>
    <name_element>
      <!--some structure-->
    </name_element>
    <some_element1>val1</some_element1>
    <some_element2>val2</some_element2>
    <!-- some more elements -->
  </item>
  <!-- lots of items -->
</inventory>

现在我想将其转换为: -

<inventory>
  <item some_element1="val1" some_element2="val2" ... >
    <name_element>
      <!-- as it is -->
    </name_element>
</inventory>

基本上我对some_elements的名称/类型一无所知,任何项目都可以包含任意数量的这些元素。我知道它们都是简单类型并且可以转换为属性。

我已经阅读了Converting XML elements to XML attributes using XSLT,它告诉我如何将所有子元素转换为属性,但是我不清楚如何排除特定的“name_element”转换为属性。

3 个答案:

答案 0 :(得分:6)

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
    <xsl:output indent="yes" method="xml"/>

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

    <xsl:template match="item">
        <xsl:copy>
            <!--apply templates for any attributes and convert 
                elements(except for name_element) in order to create all 
                attributes before creating child nodes for item element -->
            <xsl:apply-templates select="@* 
                                         | *[not(self::name_element)]"/>
            <!--apply templates to name_element and any comments or processing instructions -->
            <xsl:apply-templates select="name_element 
                                         | comment() 
                                         | processing-instruction()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="item/*[not(self::name_element)]">
        <xsl:attribute name="{local-name()}">
            <xsl:value-of select="."/>
        </xsl:attribute>
    </xsl:template>

</xsl:stylesheet>

答案 1 :(得分:3)

首先,使用身份模板按原样复制所有内容:

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

然后,为项目定义模板。您可以迭代子项,并排除您不希望转换为属性的内容。这是一个示例模板:

<xsl:template match="item">
 <xsl:copy>
   <!-- this will set children as attributes, but name_element -->
   <xsl:for-each select="*[not(local-name()='name_element')]">
        <xsl:attribute name="{local-name()}">
          <xsl:value-of select="text()"/>
        </xsl:attribute>
   </xsl:for-each>

   <!-- this preserves name_element as it is -->
   <xsl:apply-templates select="name_element"/>
 </xsl:copy>
</xsl:template>

答案 2 :(得分:1)

尝试

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="item">
        <xsl:copy>
            <xsl:apply-templates select="*[not(self::name_element)]"/>
            <xsl:apply-templates select="name_element"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="item/*[not(self::name_element)]">
        <xsl:attribute name="{name()}">
            <xsl:value-of select="."/>
        </xsl:attribute>
    </xsl:template>
</xsl:stylesheet>