2

XSLT Compiled Transform を使用する場合、出力をフォーマットすることができません。常にすべてのスペースが取り除かれ、人間が判読できる形式ではありません。

ただし、Visual Studio XSLT Debugger を使用して同じ変換を実行すると、出力はきれいにインデントされます。私のコードは次のようになります。

XDocument xDoc = XDocument.Load(_xmlFilePath, LoadOptions.PreserveWhitespace);
var xslDoc = new XmlDocument();
xslDoc.Load(_xsltFilePath);
xslDoc.PreserveWhitespace = true;
using (Stream outputFile = File.Create(_outputFileName))
{
    XsltArgumentList xsltParameter = null;
    StringReader tr = new StringReader(xslDoc.OuterXml);
    XmlReader xr = new XmlTextReader(tr);
    XslCompiledTransform transform = new XslCompiledTransform();
    XsltSettings setting = new XsltSettings();

    setting.EnableScript = true;
    transform.Load(xr, setting, new XmlUrlResolver());
    transform.Transform(xDoc.CreateReader(), xsltParameter, outputFile);
}

変換によりテキスト ファイルが作成されますが、Visual Studio の XSLT Debugger は、出力の書式設定を保持するために何が異なるのでしょうか?

私はすでにこのリンクを見てきました: XSLT Transform not indenting correctly

テキストに出力するので、これは私には当てはまりません。Stream 以外のものを使用する必要がありますか?

私のサンプル XSLT :

  <?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="text" encoding="UTF-8"/>

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

<xsl:template match="root">
    <xsl:text>{Start:</xsl:text>
    <xsl:text disable-output-escaping="yes">&#xD;</xsl:text>
    <xsl:value-of select="Child1"/>
    <xsl:text disable-output-escaping="yes">&#xD;</xsl:text>
    <xsl:value-of select="Child2"/>
    <xsl:text disable-output-escaping="yes">&#xD;</xsl:text>
    <xsl:text>End:}</xsl:text>
</xsl:template>

<?xml version="1.0" encoding="utf-8"?>
    <root>
    <Child1>Value1</Child1>
    <Child2>value2</Child2>
    </root>

期待される出力:

{Start:
 Value1
 value2
 End:}

XSLT コンパイル済み変換を使用した出力: {Start:Value1value2End:}

Visual Studio XSLT デバッガーは予想される出力形式を提供しますが、XSLT Compiled 変換はすべてのスペースと改行を取り除きます。

4

1 に答える 1

2

残念ながら、これは実際にはまだ完全なコード例ではありません。私が以前に提供したリンクを読んで、私が何を意味するかを確認してください。

とはいえ、少し努力した後、断片を取り出して、自己完結型の単一のコード例を作成することができました。あなたの懸念を確認することができました。これは、 disable-output-escaping(不要な)の使用を必要な に置き換えることで解決できましたxml:space="preserve"

XSL 変換の一部は、最初に出力を表す XML グラフを生成することです。それが完了して初めて、実際の出力が作成されます。その過程で、独立した空白がドキュメントから削除されます。を追加することxml:space="preserve"で、その独立した空白を削除しないように処理コードに指示します。

希望どおりに動作するバージョンの XSL を次に示します。

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
    <xsl:output method="text" encoding="UTF-8"/>

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

    <xsl:template match="root">
        <xsl:text>{Start:</xsl:text>
        <xsl:text xml:space="preserve">&#xA;</xsl:text>
        <xsl:value-of select="Child1"/>
        <xsl:text xml:space="preserve">&#xA;</xsl:text>
        <xsl:value-of select="Child2"/>
        <xsl:text xml:space="preserve">&#xA;</xsl:text>
        <xsl:text>End:}</xsl:text>
    </xsl:template>
</xsl:stylesheet>

ノート:

  • </xsl:stylesheet>終了タグを追加する必要がありました
  • CR エンティティ&#xD;を LF エンティティに変更しました&#xA;。改行でも機能しますが、読みやすさの観点からは改行の方が「移植性」が高いと思います。
  • 上記の例では、空白のみを含むxml:space="preserve"xsl:text要素に適用します。これにより、プロセッサがこれらの要素を削除しないことが保証されます。

その最後の点にはトレードオフがあります。xsl:textお気づきのように、空白を保持したい各ノードでその属性を指定する必要があることを意味します。別の方法として、XSL の読みやすさを犠牲にして、スタイルシート全体に属性を適用する方法があります。

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl" xml:space="preserve">
    <xsl:output method="text" encoding="UTF-8"/>

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

    <xsl:template match="root"><xsl:text>{Start:</xsl:text><xsl:text>&#xD;</xsl:text><xsl:value-of select="Child1"/><xsl:text xml:space="preserve">&#xA;</xsl:text><xsl:value-of select="Child2"/><xsl:text xml:space="preserve">&#xA;</xsl:text><xsl:text>End:}</xsl:text></xsl:template>
</xsl:stylesheet>

明らかな欠点は、各テンプレートのコンテンツには、出力に表示したい場所にのみ空白を含める必要があることです。したがって、空白を使用して XSL 自体を読みやすくすることはできません。しかし、少なくとも何度も入力する必要はありませんxml:space="preserve"。あなたが選ぶ。:)

技術的には、これは結局のところ C# に関する質問ではないことを意味していると思います。おそらく、質問からそのタグを削除する必要があります。:)

于 2015-03-19T15:08:19.993 に答える