0

私は XSLT を初めて使用し、この問題に行き詰まりました。
入力 XML

<Root>
 <Family>
   <Entity>
     <SomeElement1/>
     <Child1>
       <Element1/>
     </Child1>
     <Child2>
       <Element2/>
     </Child2>
     <Entity>
     <SomeElement1/>
     <Child1>
       <Element111/>
     </Child1>
     <Child2>
       <Element222/>
     </Child2>
   </Entity>
  </Entity>
 </Family>
</Root>

出力 XML

<Response>
 <EntityRoot>
  <SomeElement1/>
 </EntityRoot>

 <Child1Root>
   <Element1>
 </Child1Root>

 <Child2Root>
   <Element2>
 </Child2Root>

 <MetadataEntityRoot>
  <SomeElement1/>
 </MetadataEntityRoot>

 <Child1Root>
   <Element111>
 </Child1Root>

 <Child2Root>
   <Element222>
 </Child2Root>
</Response>

入力xmlからすべてをコピーする方法を知っています。しかし、子要素を除外して別のルート要素に再度コピーする方法がわかりません。

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

与えられた答えに基づいてこれを試しました

<xsl:stylesheet version="2.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="Entity">
      <EntityRoot>
        <xsl:apply-templates select="@* | node()[not(self::Child1 | self::Child2)]" />
      </EntityRoot>
      <xsl:apply-templates select="Child1 | Child2" />
    </xsl:template>
    <xsl:template match="Child1">
      <Child1Root><xsl:apply-templates select="@*|node()" /></Child1Root>
    </xsl:template>
    <xsl:template match="Child2">
      <Child2Root><xsl:apply-templates select="@*|node()" /></Child2Root>
    </xsl:template>
</xsl:stylesheet>

しかし、出力は次のようになりました。

<?xml version="1.0" encoding="UTF-8"?>
<Root>
 <Family>
   <EntityRoot>
     <SomeElement1/>
   </EntityRoot>
   <Child1Root>
       <Element1/>
    </Child1Root>
    <Child2Root>
       <Element2/>
    </Child2Root>
 </Family>
</Root>
4

1 に答える 1

2

既に持っている「すべてをコピー」する ID テンプレートに加えて、別の方法で処理したい要素に一致する特定のテンプレートを追加するだけです。名前を変更するChild1には、Child1Root次を使用できます

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

同様に、名前Child2Child2RootおよびRootに変更しResponseます。このEntityプロセスは、 Child1 と Child2を除くEntityRootすべての子要素を含む (テンプレートを適用した結果) を作成し、その後、要素の外側でこれら 2 つにテンプレートを適用すると考えることができます。EntityRoot

<xsl:template match="Entity">
  <EntityRoot>
    <xsl:apply-templates select="@* | node()[not(self::Child1 | self::Child2)]" />
  </EntityRoot>
  <xsl:apply-templates select="Child1 | Child2" />
</xsl:template>

レイヤーを完全に削除して (この場合Familyは )、その子を含めたままにするには、 を使用せずにテンプレートを使用できますcopy

<xsl:template match="Family">
  <xsl:apply-templates />
</xsl:template>
于 2013-10-14T12:41:39.730 に答える