XSLTCompiled 转换不支持文本文件的 XSLT 格式
XSLTCompiled transform not honoring XSLT Formatting for text files
在使用 XSLT 编译转换时,我无法完全格式化输出,它总是去除所有空格并且不是人类可读的形式。
但是,如果我 运行 通过 Visual studio XSLT 调试器进行相同的转换,则输出很整齐 indented.Here 我的代码如下所示:
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 调试器在保留输出格式方面有何不同?
这个我已经看过了link: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">
</xsl:text>
<xsl:value-of select="Child1"/>
<xsl:text disable-output-escaping="yes">
</xsl:text>
<xsl:value-of select="Child2"/>
<xsl:text disable-output-escaping="yes">
</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 编译转换去除了所有空格和换行符。
不幸的是,这仍然不是一个 完整的 代码示例。请阅读我之前提供的 link 以了解我的意思。
就是说,经过一些努力,我能够收集点点滴滴并创建一个独立的代码示例。我能够验证您的担忧,我可以通过将您对 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">
</xsl:text>
<xsl:value-of select="Child1"/>
<xsl:text xml:space="preserve">
</xsl:text>
<xsl:value-of select="Child2"/>
<xsl:text xml:space="preserve">
</xsl:text>
<xsl:text>End:}</xsl:text>
</xsl:template>
</xsl:stylesheet>
备注:
- 我必须添加
</xsl:stylesheet>
结束标记
- 我将 CR 实体

更改为 LF 实体 

。它也可以按照您的方式使用回车 returns,但从可读性的角度来看,我觉得换行更多 "portable"。
- 在上面的示例中,我将
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>
</xsl:text><xsl:value-of select="Child1"/><xsl:text xml:space="preserve">
</xsl:text><xsl:value-of select="Child2"/><xsl:text xml:space="preserve">
</xsl:text><xsl:text>End:}</xsl:text></xsl:template>
</xsl:stylesheet>
显然缺点是每个模板的内容必须包含空格 仅 您希望它出现在输出中的位置。所以您不能使用空格来使 XSL 本身更具可读性。但至少您不必一遍又一遍地键入 xml:space="preserve"
。你选。 :)
我想从技术上讲这意味着这毕竟不是 C# 问题。可能应该从您的问题中删除该标签。 :)
在使用 XSLT 编译转换时,我无法完全格式化输出,它总是去除所有空格并且不是人类可读的形式。
但是,如果我 运行 通过 Visual studio XSLT 调试器进行相同的转换,则输出很整齐 indented.Here 我的代码如下所示:
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 调试器在保留输出格式方面有何不同?
这个我已经看过了link: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">
</xsl:text>
<xsl:value-of select="Child1"/>
<xsl:text disable-output-escaping="yes">
</xsl:text>
<xsl:value-of select="Child2"/>
<xsl:text disable-output-escaping="yes">
</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 编译转换去除了所有空格和换行符。
不幸的是,这仍然不是一个 完整的 代码示例。请阅读我之前提供的 link 以了解我的意思。
就是说,经过一些努力,我能够收集点点滴滴并创建一个独立的代码示例。我能够验证您的担忧,我可以通过将您对 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">
</xsl:text>
<xsl:value-of select="Child1"/>
<xsl:text xml:space="preserve">
</xsl:text>
<xsl:value-of select="Child2"/>
<xsl:text xml:space="preserve">
</xsl:text>
<xsl:text>End:}</xsl:text>
</xsl:template>
</xsl:stylesheet>
备注:
- 我必须添加
</xsl:stylesheet>
结束标记 - 我将 CR 实体

更改为 LF 实体

。它也可以按照您的方式使用回车 returns,但从可读性的角度来看,我觉得换行更多 "portable"。 - 在上面的示例中,我将
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>
</xsl:text><xsl:value-of select="Child1"/><xsl:text xml:space="preserve">
</xsl:text><xsl:value-of select="Child2"/><xsl:text xml:space="preserve">
</xsl:text><xsl:text>End:}</xsl:text></xsl:template>
</xsl:stylesheet>
显然缺点是每个模板的内容必须包含空格 仅 您希望它出现在输出中的位置。所以您不能使用空格来使 XSL 本身更具可读性。但至少您不必一遍又一遍地键入 xml:space="preserve"
。你选。 :)
我想从技术上讲这意味着这毕竟不是 C# 问题。可能应该从您的问题中删除该标签。 :)