2011-02-04 3 views
2

私はちょうどXSLTを使い始めました。そして、アイデンティティテンプレートに慣れ親しんでいます。大部分は、このトピックに関するいくつかの素晴らしい答えを提供してくれたDimitre Novatchev,に感謝します。選択したノードの子を保持する、恒等変換をXSLTに書き込むにはどうすればよいですか?

大規模なスキーマファイルのいくつかの要素だけを分離してコピーしようとするXML-to-XML変換を実行しています。

XSDソース

<?xml version="1.0" encoding="utf-8"?> 
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" attributeFormDefault="unqualified" version="1.0"> 

<xsd:simpleType name="Alpha"> 
    <xsd:restriction base="xsd:decimal"> 
     <xsd:fractionDigits value="1"/> 
     <xsd:minInclusive value="0.0"/> 
     <xsd:maxInclusive value="100.0"/> 
    </xsd:restriction> 
</xsd:simpleType> 

<xsd:simpleType name="Bravo"> 
    <xsd:annotation> 
     <xsd:documentation> 
      Bravo data type. 
     </xsd:documentation> 
    </xsd:annotation> 
    <xsd:restriction base="xsd:integer"/> 
</xsd:simpleType> 

<xsd:simpleType name="Charlie"> 
    <xsd:annotation> 
     <xsd:documentation> 
     Charlie data type. 
     </xsd:documentation> 
    </xsd:annotation> 
    <xsd:restriction base="xsd:integer"/> 
</xsd:simpleType> 

<xsd:simpleType name="Delta"> 
    <xsd:annotation> 
     <xsd:documentation> 
     Delta data type. 
     </xsd:documentation> 
    </xsd:annotation> 
    <xsd:restriction base="xsd:integer"/> 
</xsd:simpleType> 
</xsd:schema> 

XSLTスタイルシート

<?xml version="1.0"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
<xsl:output omit-xml-declaration="no" indent="yes" /> 
<!-- identity template --> 
<xsl:template match="/ | node() | @*"> 
<xsl:copy> 
<xsl:apply-templates select="node() | @*"/> 
</xsl:copy> 
</xsl:template> 
<xsl:template match="*/node()[ 
           not (@name='Alpha') 
           and 
           not (@name='Charlie') 
           ] 

           "/> 
</xsl:stylesheet> 

結果

<?xml version="1.0"?> 
<xsd:schema attributeFormDefault="unqualified" version="1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
<xsd:simpleType name="Alpha"></xsd:simpleType> 
<xsd:simpleType name="Charlie"></xsd:simpleType> 
</xsd:schema> 
:ここではデータの多く-簡易版です

これは本当に近いですが、copy-ofを実行したかのように、選択したノードのアルファとチャーリーの子が結果に必要です。

私は必要なもの

<?xml version="1.0"?> 
<xsd:schema attributeFormDefault="unqualified" version="1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
<xsd:simpleType name="Alpha"> 
     <xsd:restriction base="xsd:decimal"> 
     <xsd:fractionDigits value="1"/> 
     <xsd:minInclusive value="0.0"/> 
     <xsd:maxInclusive value="100.0"/> 
    </xsd:restriction> 
</xsd:simpleType> 
<xsd:simpleType name="Charlie"> 
    <xsd:annotation> 
     <xsd:documentation> 
      Charlie data type. 
     </xsd:documentation> 
    </xsd:annotation> 
    <xsd:restriction base="xsd:integer"/> 
</xsd:simpleType> 
</xsd:schema> 

copy-of,で要素を選択するか、私はアルファとチャーリーの子供たちに再帰的にしたい私のmatch句で指定する方法はありますか?

ありがとうございます!

+0

良い質問、+1。実際の原因の説明と簡単な修正については、私の答えを参照してください。:) –

答えて

2

"Bravo"と "Delta"の要素を除いて、ロジックをすべてコピーに戻す必要があります

空のテンプレートは次のようになります。

<xsl:template match="xs:simpleType[@name[.='Bravo' or .='Delta']]" 
       xmlns:xs="http://www.w3.org/2001/XMLSchema"/> 

:念のため...

、名前空間を追加するもう一つの方法は、より多くのセマンティック:

<xsl:template match="/*/*[not(@name[.='Alpha' or .='Charlie'])]"/> 
+0

Alejandro、アイデアのおかげで、実際のアプリケーションでは、何百もの要素から名前でいくつかの項目を選択しています。必要な要素はsimpleType、complexTypeなどです。したがって、Alphaと私が欲しくないものを指定するのではなく、名前でチャーリー。 –

+0

@MW Frost:その後、スタイルシートをリファクタリングする必要があります。私の更新を確認してください。 –

+0

アレハンドロ、これは動作します。私はsimpleType、complexTypeなどの新しいテンプレートを作って、それぞれに同じマッチ句を使うことができます:[not(@name [。= 'Alpha' or。= 'Charlie'])] –

2

あるいは、@Alejandroの善良な答えに、コード内の問題を修正することができます

ちょうどを変更:

<xsl:template match= 
"*/node()[ 
      not (@name='Alpha') 
      and 
      not (@name='Charlie') 
      ] 
    "/> 

へ:

<xsl:template match= 
"/*/node()[ 
      not (@name='Alpha') 
      and 
      not (@name='Charlie') 
      ] 
    "/> 

説明:元々提供された "削除テンプレートには" あまりにも多くのノードに一致しています。トップエレメントの子要素にのみ一致する必要があります。

+0

はい、これはまさに私のコードの問題でした。 +1と両方のおかげでy'all。 –

関連する問題