4

特定の要素 (この場合は親) の id 属性を、親の子内の新しい要素にコピーしたいと考えています。

私のXMLは次のとおりです。

<wrapper>
    <parent id="1">
         <child>
            content
         </child>
    </parent>
</wrapper>

出力を次のようにする必要があります。

<wrapper>
    <parent>
        <child>
            <parentid>1</parentid> 
            content
        </child>
    </parent>
</wrapper>

以下の例から、これは私が望むことを行いますが、新しい要素を親に置き、子に置きたいのです:

<xsl:template match="parent[@id]">
    <parent>
        <xsl:apply-templates select="@*[name() != 'id']" />
            <parentid>
                <xsl:value-of select="@id" />
            </parentid>
        <xsl:apply-templates select="node()"/>
    </parent>
</xsl:template>

上記をいじっていますが、まだ思い通りにできません。前もって感謝します。

4

1 に答える 1

8

これがすべての属性に必要なのか、 id属性だけに必要なのか、または 1 つの要素の属性だけなのか、すべての要素なのかはわかりません。

すべての要素のid属性に対してそれを行いたいが、他の属性はそのままにしておくと仮定しましょう。次に、そのような要素とid属性を一致させるテンプレートを次のように作成します。

<xsl:template match="*[@id]">

この中で、次のように、現在の要素名に基づいて新しい要素を作成できます。

     <xsl:element name="{name()}id">
        <xsl:value-of select="@id" />
     </xsl:element>

この XSLT を試してみてください

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

   <xsl:template match="*[@id]">
      <xsl:copy>
         <xsl:apply-templates select="@*[name() != 'id']" />
         <xsl:element name="{name()}id">
            <xsl:value-of select="@id" />
         </xsl:element>
         <xsl:apply-templates select="node()"/>
      </xsl:copy>
   </xsl:template>
</xsl:stylesheet>

新しい要素名を動的に作成する際の属性値テンプレート (中括弧) の使用に注意してください。また、子要素が作成された後に要素の属性を出力するとエラーと見なされるため、新しい子要素を作成する前に他の属性を出力する必要があることに注意してください。

もちろん、特定の要素のid属性のみが必要な場合は、2 番目のテンプレートをこれに単純化できます。

<xsl:template match="parent[@id]">
   <parent>
      <xsl:apply-templates select="@*[name() != 'id']" />
      <parentid>
         <xsl:value-of select="@id" />
      </parentid>
      <xsl:apply-templates select="node()"/>
   </parent>
</xsl:template>

しかし、すべての属性を要素に変換したい場合は、次のように完全に一般的な方法でこれを行うことができます。

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

   <xsl:template match="@*">
      <xsl:element name="{name(..)}{name()}">
         <xsl:value-of select="." />
      </xsl:element>
   </xsl:template>
</xsl:stylesheet>

編集:

子要素の子としてid属性を実際に追加する必要がある場合は、少し調整が必要です。まず、要素がコピーされた時点で親のid属性が出力されないようにするためのテンプレートが必要です。

<xsl:template match="parent/@id" />

次に、親要素の子と一致するテンプレートが必要です

<xsl:template match="parent[@id]/*[1]">

(この場合、常に最初の子要素になると想定しています。特定の子要素が必要な場合は、ここで名前を使用してください)

このテンプレート内で、親のid属性を使用して新しい要素を作成できます。

このXSLTを試してください

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

   <xsl:template match="parent/@id" />

   <xsl:template match="parent[@id]/*[1]">
      <xsl:copy>
         <xsl:apply-templates select="@*" />
         <parentid>
           <xsl:value-of select="../@id" />
         </parentid>
         <xsl:apply-templates select="node()"/>
      </xsl:copy>
   </xsl:template>
</xsl:stylesheet>
于 2013-09-25T22:47:33.047 に答える