2017-11-15 239 views
0

XSLT経由でXMLファイルから空のタグや改行を削除したい。xsltで空タグと改行を削除するには?

基準1: 改行のみ、すなわちXMLにはインデント残るべき、テキストノード内削除する必要があります。

基準2: 任意のOSで動作する必要があります。

基準3: 可能であれば、XMLに他の変更はありません。

例のXMLは次のようになります。

<?xml version="1.0" encoding="UTF-8"?> 
<Container xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <tag1>22</tag1> 
    <tag2>33</tag2> 
    <tag3/> 
    <minimalValue/> 
    <maximalValue/> 
    <minimalFee/> 
    <maximalFee/> 
    <tag4>This is text with a 
     line break. 
    </tag4> 
</Container> 

結果は次のようになります。

<Container xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <tag1>22</tag1> 
    <tag2>33</tag2> 
    <tag4>This is text with a line break.</tag4> 
</Container> 

答えて

1

:しかし、私は、次のテンプレートを使用して上記を達成しました。

インデントを使用する場合indent="yes"

空のタグを削除するには、あなたが要素match="*")のテンプレートを必要とする、 しかし、この要素は非空白のみ コンテンツ([normalize-space()])を持っていることを要求述語を持ちます。 空の要素のテンプレートは存在しないため、コピーされません。

改行を削除するには、text()ノードのテンプレート、正規化されたコンテンツをコピーする が必要です。だから、総括する

、あなたはもう少し簡潔 他の提案よりも、次のスクリプトを使用することができます。私は、属性ノードを処理するために、2ヶ所で|@*を追加

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 

    <xsl:template match="*[normalize-space()]|@*"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="text()"> 
    <xsl:value-of select="normalize-space()"/> 
    </xsl:template> 
</xsl:stylesheet> 

注意、のよう アイデンティティテンプレート。 しかし、ソースXMLには属性ノードが含まれていないので、これらの追加がなくても できます。

+0

こんにちは@Valdi_Bo、ありがとうございます。しかし、私はまだそれが本当にどのように動作するかは分かりません。 ** normalize-space()**は[docs](https://www.w3.org/TR/1999/REC-xpath-19991116/#function-normalize-space)の種類のより高度なトリミング関数は、タグで使用されたときにコンテキストノードに適用されていると理解しています。ただし、テンプレートの述部として使用します。ノードをスキップするには、空のタグをfalseに評価する必要があります。しかし、これは、 "先頭と末尾の空白を取り除き、一連の空白文字を置き換える"ことと関係があります。 –

+0

@Viktor:* normalize-space *の最初の使い方は、単に "白い"文字を正規化することです。 詳細については、http://www.xsltfunctions.com/xsl/fn_normalize-space.htmlを参照してください。 この機能は、** boolean **コンテキストでも使用できます。* 他の言葉:* "白"文字以外のものがありますか?* 私は使用した述語の中で、何をチェックしますか? *現在の要素の内容は空ではありませんか?*(空白のみの内容は空白として扱われます)。 –

+0

ありがとう!このリンクは便利です。 –

0

私は、これはそれを行うための最善の方法であるかどうかわからないです。あなたはxsl:outputomit-xml-declaration 属性を使用する必要があり、最初のXML宣言を省略する

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

    <xsl:template match="child::node()[not(self::text())]|@*"> 
     <xsl:if test="normalize-space(string(.)) != ''"> 
      <xsl:copy> 
       <xsl:apply-templates select="node()|@*"/> 
      </xsl:copy> 
     </xsl:if> 
    </xsl:template> 

    <xsl:template match="text()"> 
     <xsl:value-of select="normalize-space(.)"/> 
    </xsl:template> 
</xsl:stylesheet> 
関連する問題