Saxon XSLT:序列化程序产生奇怪的缩进
Saxon XSLT: Serializer producing weird indents
我正在使用 Saxon HE 9.5.1.8 将 XML 转换为另一个 XML 文件。
我的问题是,由 Saxon 的 Serializer() class 编写的 XML 内容打印出几个我不想在其中出现的额外缩进。我假设这是 "wrong" 因为我在使用 DomDestination() class 时得到了预期的输出(但随后缺少外部 XML 文档信息)或其他 XSL 转换器,如Visual Studio / .NET Framework 附带的一个。
这是输入 XML:
<?xml version="1.0"?>
<catalog>
<book id="bk101">
<author>Gambardella, Matthew</author>
<title>XML Developer's Guide</title>
<genre>Computer</genre>
<price>.95</price>
<publish_date>2000-10-01</publish_date>
</book>
<book id="bk102">
<author>Ralls, Kim</author>
<title>Midnight Rain</title>
<genre>Fantasy</genre>
<price>.95</price>
<publish_date>2000-12-16</publish_date>
</book>
这是 XLST 文件:
<?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="xml" indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="book">
<book>
<xsl:copy-of select="@*|book/@*" />
<xsl:for-each select="*">
<xsl:attribute name="{name()}">
<xsl:value-of select="text()"/>
</xsl:attribute>
</xsl:for-each>
</book>
</xsl:template>
</xsl:stylesheet>
这是预期的输出:
<?xml version="1.0" encoding="utf-8"?>
<catalog>
<book id="bk101" author="Gambardella, Matthew" title="XML Developer's Guide" genre="Computer" price=".95" publish_date="2000-10-01" />
<book id="bk102" author="Ralls, Kim" title="Midnight Rain" genre="Fantasy" price=".95" publish_date="2000-12-16" />
</catalog>
这是使用 Saxon 时的输出:
<?xml version="1.0" encoding="UTF-8"?>
<catalog>
<book id="bk101"
author="Gambardella, Matthew"
title="XML Developer's Guide"
genre="Computer"
price=".95"
publish_date="2000-10-01"/>
<book id="bk102"
author="Ralls, Kim"
title="Midnight Rain"
genre="Fantasy"
price=".95"
publish_date="2000-12-16"/>
</catalog>
有人知道如何抑制或修改 Saxon 的这种行为吗?这是用于调用 Saxon API:
的 C# 代码
public Stream Transform(string xmlFilePath, string xsltFilePath)
{
var result = new MemoryStream();
var xslt = new FileInfo(xsltFilePath);
var input = new FileInfo(xmlFilePath);
var processor = new Processor();
var compiler = processor.NewXsltCompiler();
var executable = compiler.Compile(new Uri(xslt.FullName));
var destination = new Serializer();
destination.SetOutputStream(result);
using(var inputStream = input.OpenRead())
{
var transformer = executable.Load();
transformer.SetInputStream(inputStream, new Uri(input.DirectoryName));
transformer.Run(destination);
}
result.Position = 0;
return result;
}
尝试将 http://saxonica.com/documentation9.5/extensions/output-extras/line-length.html 设置为一个非常大的值以避免将属性放在新行上:<xsl:output xmlns:saxon="http://saxon.sf.net/" saxon:line-length="1000"/>
.
您的目标是让多个处理器以相同的格式生成输出,这是无可救药的误导。如果您选择缩进输出,则尤其如此:规范将其完全留给实现如何进行缩进,只说目标是使其易于阅读。 (并对可以插入额外空格的位置施加限制。)
很抱歉,您不觉得 Saxon 包装长属性列表的方式令人满意,但这完全符合规范的文字和精神。没有它,如果您有一个包含八个名称空间声明的元素,您可以轻松获得 400 个字符长的行,我当然不认为这是人类可读的。
从词法上比较两个 XML 文档永远行不通的原因有很多。例如,属性可以采用不同的顺序。有两种比较 XML 的方法:使用 "Canonical XML" 处理器将文档转换为规范形式,或者在树级别比较它们,例如使用 XPath 2.0 deep-equal() 函数。理想情况下(特别是如果您想知道差异在哪里,而不仅仅是差异是否存在),请使用专业的 XML 比较工具,例如 DeltaXML.
值得一提的是,当我们进行单元测试时,我们首先尝试对结果进行词法比较。如果失败,我们解析两个文档并使用 saxon:deep-equal() 比较它们,这是 deep-equal() 函数的修改形式,可以很好地控制比较规则,例如处理空白和命名空间。
我正在使用 Saxon HE 9.5.1.8 将 XML 转换为另一个 XML 文件。
我的问题是,由 Saxon 的 Serializer() class 编写的 XML 内容打印出几个我不想在其中出现的额外缩进。我假设这是 "wrong" 因为我在使用 DomDestination() class 时得到了预期的输出(但随后缺少外部 XML 文档信息)或其他 XSL 转换器,如Visual Studio / .NET Framework 附带的一个。
这是输入 XML:
<?xml version="1.0"?>
<catalog>
<book id="bk101">
<author>Gambardella, Matthew</author>
<title>XML Developer's Guide</title>
<genre>Computer</genre>
<price>.95</price>
<publish_date>2000-10-01</publish_date>
</book>
<book id="bk102">
<author>Ralls, Kim</author>
<title>Midnight Rain</title>
<genre>Fantasy</genre>
<price>.95</price>
<publish_date>2000-12-16</publish_date>
</book>
这是 XLST 文件:
<?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="xml" indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="book">
<book>
<xsl:copy-of select="@*|book/@*" />
<xsl:for-each select="*">
<xsl:attribute name="{name()}">
<xsl:value-of select="text()"/>
</xsl:attribute>
</xsl:for-each>
</book>
</xsl:template>
</xsl:stylesheet>
这是预期的输出:
<?xml version="1.0" encoding="utf-8"?>
<catalog>
<book id="bk101" author="Gambardella, Matthew" title="XML Developer's Guide" genre="Computer" price=".95" publish_date="2000-10-01" />
<book id="bk102" author="Ralls, Kim" title="Midnight Rain" genre="Fantasy" price=".95" publish_date="2000-12-16" />
</catalog>
这是使用 Saxon 时的输出:
<?xml version="1.0" encoding="UTF-8"?>
<catalog>
<book id="bk101"
author="Gambardella, Matthew"
title="XML Developer's Guide"
genre="Computer"
price=".95"
publish_date="2000-10-01"/>
<book id="bk102"
author="Ralls, Kim"
title="Midnight Rain"
genre="Fantasy"
price=".95"
publish_date="2000-12-16"/>
</catalog>
有人知道如何抑制或修改 Saxon 的这种行为吗?这是用于调用 Saxon API:
的 C# 代码public Stream Transform(string xmlFilePath, string xsltFilePath)
{
var result = new MemoryStream();
var xslt = new FileInfo(xsltFilePath);
var input = new FileInfo(xmlFilePath);
var processor = new Processor();
var compiler = processor.NewXsltCompiler();
var executable = compiler.Compile(new Uri(xslt.FullName));
var destination = new Serializer();
destination.SetOutputStream(result);
using(var inputStream = input.OpenRead())
{
var transformer = executable.Load();
transformer.SetInputStream(inputStream, new Uri(input.DirectoryName));
transformer.Run(destination);
}
result.Position = 0;
return result;
}
尝试将 http://saxonica.com/documentation9.5/extensions/output-extras/line-length.html 设置为一个非常大的值以避免将属性放在新行上:<xsl:output xmlns:saxon="http://saxon.sf.net/" saxon:line-length="1000"/>
.
您的目标是让多个处理器以相同的格式生成输出,这是无可救药的误导。如果您选择缩进输出,则尤其如此:规范将其完全留给实现如何进行缩进,只说目标是使其易于阅读。 (并对可以插入额外空格的位置施加限制。)
很抱歉,您不觉得 Saxon 包装长属性列表的方式令人满意,但这完全符合规范的文字和精神。没有它,如果您有一个包含八个名称空间声明的元素,您可以轻松获得 400 个字符长的行,我当然不认为这是人类可读的。
从词法上比较两个 XML 文档永远行不通的原因有很多。例如,属性可以采用不同的顺序。有两种比较 XML 的方法:使用 "Canonical XML" 处理器将文档转换为规范形式,或者在树级别比较它们,例如使用 XPath 2.0 deep-equal() 函数。理想情况下(特别是如果您想知道差异在哪里,而不仅仅是差异是否存在),请使用专业的 XML 比较工具,例如 DeltaXML.
值得一提的是,当我们进行单元测试时,我们首先尝试对结果进行词法比较。如果失败,我们解析两个文档并使用 saxon:deep-equal() 比较它们,这是 deep-equal() 函数的修改形式,可以很好地控制比较规则,例如处理空白和命名空间。