2016-04-09 24 views
-1

私は、変換されたXMLを少し読みやすくする、つまり要素間のcrやタブなどの空白を保存するという新しい要件があります。XSLT:要素間の空白を保持する方法

空白を保存する方法を理解できないようです。

誰かが助けてくれますか?

XMLファイル

<?xml version="1.0" encoding="utf-8"?> 
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"> 
    <Fragment> 
    </Fragment> 
</Wix> 

XSLファイル:

<?xml version="1.0" encoding="UTF-8"?> 
    <xsl:stylesheet version="2.0" 
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
        xmlns:m="http://schemas.microsoft.com/wix/2006/wi"> 
    <xsl:preserve-space elements="*" /> 
    <xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
    </xsl:template> 
    <xsl:template match="/m:Wix"> 
    <xsl:message>Matched Wix</xsl:message> 
    <xsl:copy> 
     <!-- Insert the new include processing instruction --> 
     <xsl:processing-instruction name="include"> 
     <xsl:text>$(sys.CURRENTDIR)src/includes/globals.wxi </xsl:text> 
     </xsl:processing-instruction> 
     <!-- place the existing children into the output --> 
     <xsl:apply-templates select="@* | *"/> 
    </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

電流出力:

<?xml version="1.0" encoding="UTF-8"?><Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"><?include $(sys.CURRENTDIR)src/includes\globals.wxi ?><Fragment> 
    </Fragment></Wix> 

所望の出力

<?xml version="1.0" encoding="UTF-8"?> 
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"> 
    <?include $(sys.CURRENTDIR)src/includes\globals.wxi ?> 
    <Fragment> 
    </Fragment> 
</Wix> 
+0

"xlst"とは何ですか?良い質問 !!それは私がMacでオートコレクトを再タイピングしようとしていることを意味します。 – garyM

答えて

1

入力には、Fragment要素の兄弟である2つとFragment要素の子である2つの空白テキストノードがあります。

m:Wix要素のテンプレートが無視するため、最初の2つは出力にコピーされません。<xsl:apply-templates select="@* | *"/>はテキストノードの子ではなく要素の子のみを選択します。

Fragmentの空白テキストコンテンツが処理され、出力に保持されます。

今、あなたは質問に2つのことを言っています:(a)出力を読みやすくしたい、そして(b)入力に存在する空白を保存したいとします。私は(b)が(a)を達成する最良の方法ではないことを示唆しています。 (a)を達成する最良の方法は、入力に存在する空白を無視し、xsl:output indent="yes"を使用して出力に新しい空白を追加することです。

ただし、入力から出力に空白をコピーする場合は、要素の子を処理するときにselect="*"ではなくselect="node()"を使用する必要があります。

1

プロセス命令の前と後に次のテキストを追加することで&#9;、改行を使用して&#xa;とタブエンティティを考えてみましょう。

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="2.0" 
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
        xmlns:m="http://schemas.microsoft.com/wix/2006/wi"> 
    <xsl:output version="1.0" encoding="UTF-8" indent="yes" /> 
    <xsl:preserve-space elements="*" /> 

    <xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
    </xsl:template> 
    <xsl:template match="/m:Wix"> 
    <xsl:message>Matched Wix</xsl:message> 
    <xsl:copy> 
     <xsl:text>&#xa; &#9;</xsl:text>  
     <!-- Insert the new include processing instruction --> 
     <xsl:processing-instruction name="include"> 
     <xsl:text>$(sys.CURRENTDIR)src/includes/globals.wxi </xsl:text> 
     </xsl:processing-instruction> 
     <xsl:text>&#xa; &#9;</xsl:text>  
     <!-- place the existing children into the output --> 
     <xsl:apply-templates select="@* | *"/>   
    </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

はまた、より正確な位置合わせのためのタブの代わりに、複数の非ブレークスペースエンティティ&#160;を使用します:そして、上部に向かってインデント出力ヘッダを追加してください

<xsl:text>&#xa;&#160;&#160;&#160;&#160;</xsl:text>  

出力

<?xml version="1.0" encoding="UTF-8"?> 
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"> 
    <?include $(sys.CURRENTDIR)src/includes/globals.wxi?> 
    <Fragment> 
    </Fragment> 
</Wix> 
+0

チップをありがとう。フォーマットは一貫しておらず、異なるソースからの異なるファイルです。フォーマットをハードコーディングすることは実行可能な解決策ではありませんが、フォールバックの位置としてそれを必要とする可能性があります。 – garyM

0

かなりの印刷に最適なツールはxmlintです。

xmllint --format old.xml > new.xml 

しかし、処理命令を追加しています。だからxsltが必要です。

<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:m="http://schemas.microsoft.com/wix/2006/wi" 
    exclude-result-prefixes="m"> 

    <xsl:output method="xml" encoding="UTF-8" indent="yes"/> 
    <xsl:preserve-space elements="*" /> 

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

    <xsl:template match="m:Wix"> 
     <xsl:message>Matched Wix</xsl:message> 
     <Wix> 

      <xsl:call-template name="CR"/> 
      <xsl:call-template name="TAB"/> 

      <!-- Insert the new include processing instruction --> 
      <xsl:processing-instruction name="include"> 
       <xsl:text>$(sys.CURRENTDIR)src/includes/globals.wxi</xsl:text> 
      </xsl:processing-instruction> 

      <!-- place the existing children into the output --> 
      <xsl:apply-templates/> 
     </Wix> 
    </xsl:template> 

    <xsl:template match="m:Fragment"> 
     <Fragment> 
      <xsl:apply-templates/> 
     </Fragment> 
    </xsl:template> 

    <xsl:template name="CR"> 
     <xsl:text>&#xa;</xsl:text>  
    </xsl:template> 

    <xsl:template name="TAB"> 
     <xsl:text>&#9;</xsl:text> 
    </xsl:template> 

</xsl:stylesheet> 

実際のXMLがより複雑になる場合は、最初にxmllintを使用することをお勧めします。次に、単純なxsltを実行して処理命令を追加します。 Xmllintはきれいに空白を認識しているので、xsltを焼き付ける必要があります。

関連する問題