【问题标题】:XSLTCompiled transform not honoring XSLT Formatting for text filesXSLTCompiled 转换不支持文本文件的 XSLT 格式
【发布时间】:2015-03-19 01:36:37
【问题描述】:

使用 XSLT 编译转换时,我无法将输出完全格式化,它总是去除所有空格并且不是人类可读的形式。

但是,如果我通过 Visual Studio XSLT 调试器运行相同的转换,则输出会整齐地缩进。这是我的代码的样子:

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 编译转换的输出: {Start:Value1value2End:}

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

【问题讨论】:

  • 请更清楚地说明您的问题。请通过包括每种输出的实际示例,准确地解释您现在得到什么输出,以及您想要什么输出?请提供a good, minimal, complete code example,清楚地说明您的问题。
  • 添加了我的示例,如果您需要其他任何东西,请告诉我
  • 当您使用&amp;#xD;&amp;#xA; 作为行尾时会发生什么? Windows 使用 CR/LF 作为行尾,而不仅仅是 CR。一些应用程序可能只接受 CR 或两者旁边的 LF。
  • 仍然产生相同的输出,没有空格它与使用 Stream 或 TextWriter 有关吗?与 XMlWriter 不同,我无法指定 outputsettings 属性来尊重 XSl 的格式?

标签: xslt-1.0 xslcompiledtransform outputformat


【解决方案1】:

不幸的是,这仍然不是一个真正的完整代码示例。请阅读我之前提供的链接以了解我的意思。

也就是说,经过一番努力,我能够利用零碎的东西创建一个独立的、独立的代码示例。我能够验证您的问题,我可以通过将您对 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>

注意事项:

  • 我必须添加 &lt;/xsl:stylesheet&gt; 结束标签
  • 我将 CR 实体 &amp;#xD; 更改为 LF 实体 &amp;#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# 问题。可能应该从您的问题中删除该标签。 :)

【讨论】:

  • 对不起,我错了 XMLWriter 不适用于我。但是这样做仍然不会缩进我的输出。还有其他建议吗?
  • @user3313541:我能够根据您提供的内容创建一个很好的工作代码示例。请参阅上面的编辑以回答您的 XSL 问题。 :)
  • 成功了,谢谢,我很感激我不确定问题出在哪里,Happy 可以在 XSLT 中解决它。
  • xml:space="preserve" 确实是一个关键因素,没有它,输出就不会缩进。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-05-25
  • 1970-01-01
  • 1970-01-01
  • 2010-11-22
  • 2013-11-25
  • 2016-10-03
相关资源
最近更新 更多