XSLTC编译转换不遵守文本文件的XSLT格式

时间:2015-03-19 01:36:38

标签: xslt-1.0 xslcompiledtransform outputformat

使用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调试器做什么不同,它保留了输出格式?

我已经看过这个链接:XSLT Transform not indenting properly

当我输出到文本时,这不适用于我。我应该使用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 Compiled变换输出: {Start:Value1value2End:}

Visual Studio XSLT调试器为我提供了预期的输出格式,但XSLT Compiled转换剥离了所有空格和新行。

1 个答案:

答案 0 :(得分: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#问题。可能应该从您的问题中删除该标记。 :)