4

私は次の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 の名前/タイプについては何も知りません。どのアイテムにもこれらの要素がいくつでもある可能性があります。それらはすべて単純な型であり、属性に変換できることは知っています。

XSLT を使用して XML 要素を XML 属性に変換する方法を読みましたが、すべての子要素を属性に変換する方法を説明していますが、特定の「name_element」を属性に変換しないようにする方法が明確ではありません。

4

3 に答える 3

7
<?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>
于 2012-07-05T15:57:46.367 に答える
3

まず、ID テンプレートを使用して、すべてのものをそのままコピーします。

<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>
于 2012-07-05T15:57:37.673 に答える
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>
于 2012-07-05T15:57:54.023 に答える