2017-12-14 21 views
-1

ヌルノードを削除する必要がありますが、特定の属性「DELETE」の値としてスペースを持つノードを保持する必要があります。私はXSLに慣れていません...ヌル値は削除できますが、スペースの値は保持できますか?XSL - ヌルタグの削除とスペースの保持

これは、好ましくは、アクション「DELETE」を持つノードのみです。たとえば、アクションが「DELETE」の場合、他のノード名が何であるかに関係なく(変更されるため)、ヌル値の子ノードを削除する必要があります。これが不可能な場合は、XMLファイル全体からヌル値を取り除くために解決します。このコードは以下のとおりです。ただし、スペースは保持されず、属性「DELETE」だけではありません。以下の例。

<?xml version="1.0" encoding="utf-8"?> 
<test xmlns:n0="http://mynamespace"> 
<Value Action="DELETE"> 
    <Example1> </Example1> 
    <Test2 /> 
    <Example3></Example3> 
</Value> 
<Value Action="UPDATE"> 
    <space> </space> 
    <null /> 
    <null2></null2> 
</Value> 
</test> 

期待される結果:

<?xml version="1.0" encoding="utf-8"?> 
<test xmlns:n0="http://mynamespace"> 
    <Value Action="DELETE"> 
    <Example1> </Example1> 
    </Value> 
    <Value Action="UPDATE"> 
    <space> </space> 
    <null /> 
    <null2></null2> 
    </Value> 
</test> 

がすべてNULL削除:XSL下記参照、

<?xml version="1.0" encoding="UTF-8"?> 

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
version="1.0"> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="*"> 
    <xsl:if test=". != '' or ./@* != ''"> 
     <xsl:element name="{local-name()}"> 
      <xsl:apply-templates select="@* | node()" /> 
     </xsl:element> 
    </xsl:if> 
    </xsl:template> 

    <xsl:template match="@*"> 
     <xsl:attribute name="{local-name()}"> 
      <xsl:value-of select="." /> 
     </xsl:attribute> 
    </xsl:template> 
     <xsl:template match="text() | comment() | processing-instruction()"> 
     <xsl:copy /> 
    </xsl:template> 
</xsl:stylesheet> 
+0

私は私の質問を更新しました。ありがとう。 – Toya

+0

質問が編集されました。 – Toya

答えて

0

コピーし、次のテンプレート内のノードを避け、すべてのノードと一致して(編集):

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">  
    <xsl:output method="xml" encoding="utf-8" indent="no" omit-xml-declaration="yes"/> 
    <!--copy all nodes--> 
    <xsl:template match="@*|node()">    
     <xsl:copy>     
      <xsl:apply-templates select="@*|node()" />   
     </xsl:copy>   
    </xsl:template> 
    <!--preventing spaces between nodes--> 
    <xsl:template match="text()"> 
     <xsl:value-of select="normalize-space()" /> 
    </xsl:template>  
    <!--match all elements which contain null for DELETE with doing nothing in template-->  
    <xsl:template match="/test/Value[@Action='DELETE']/*[contains(name(), 'null')]" /> 

</xsl:stylesheet> 

結果(に編集):

<test xmlns:n0="http://mynamespace"> 
    <Value Action="DELETE"> 
     <space/> 
    </Value> 
    <Value Action="UPDATE"> 
     <space/> 
     <null/> 
     <null2/> 
    </Value> 
</test> 
+0

ノード間のスペースを削除するには、 ''も考慮してください。 – Parfait

+0

これはノード名 "null"と "null2"にのみ固有のものですか?私はそのアクションを持つ任意のノードのnull値を削除したいと考えています。 – Toya

+0

@Toya XSLコードを編集しましたが、今や動的です。名前に "null"が含まれているすべての要素が削除されます(例: "tttnull"、 "null2"、または "null"などの要素が削除されます)。また、ノード間のスペースを防ぐために追加されました - Parfaitに感謝します。 –

1

あなたが必要です:

  1. アイデンティティテンプレートをすべての入力をコピーします。

  2. 次の両方の基準を満たす各ノードテンプレートマッチングは:

    • それは、属性が DELETE に設定ノードアクションと内に含まれている
    • は、その名前がヌルが含まれています

    sucを無視するhノード。

    これは、各ノード名(ヌルnull2、...)のための個々のテンプレート よりも一般的で簡潔なソリューションです。

  3. オプションで、空白のみのテキストノードをテンプレートにして、 を含むテンプレート改行 char。理由はブロックすることです改行テキストノード あなたのタグの間に、しかし "合格"。スペースはspaceタグ内に含まれています。

だから、全体のスクリプトは以下のようになります。

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

    <xsl:template match="Value[@Action = 'DELETE']/*[contains(name(), 'null')]"/> 

    <xsl:template match="text()[not(normalize-space())][contains(.,'&#xA;')]"/> 

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

これは私には役に立たなかった。 – Toya

+0

@Valdi_Boあなたのコードは、値がの場合、削除するノードが "null"で始まる場合にのみ有効です。これは動作しません。安全な方法は含まれているを使用することです、私の編集例を参照してください。 –

+0

サンプルタグのみを指定しました。名前は** start **と* null *です。 ** ** null *を含むすべてのタグを削除するタスクであれば、2番目の述語は* starts * with *の代わりに* contains * functionを含める必要があります(これはスクリプトで変更したものです)。 –

関連する問題