Saxon XSLT:Serializer产生奇怪的缩进

时间:2015-02-05 12:27:10

标签: c# xslt saxon

我使用Saxon HE 9.5.1.8将XML转换为另一个XML文件。

我的问题是Saxon的Serializer()类编写的XML内容打印出了我不想要的其他几个缩进。我假设这是"错误"因为我在使用DomDestination()类(但后来缺少外部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>$44.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>$5.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="$44.95" publish_date="2000-10-01" />
  <book id="bk102" author="Ralls, Kim" title="Midnight Rain" genre="Fantasy" price="$5.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="$44.95"
         publish_date="2000-10-01"/>
    <book id="bk102"
         author="Ralls, Kim"
         title="Midnight Rain"
         genre="Fantasy"
         price="$5.95"
         publish_date="2000-12-16"/>
</catalog>

有人知道如何抑制或修改撒克逊人的这种行为吗?这是用于调用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;
}

2 个答案:

答案 0 :(得分:2)

尝试将http://saxonica.com/documentation9.5/extensions/output-extras/line-length.html设置为一个非常大的值,以避免将这些属性放在新行上:<xsl:output xmlns:saxon="http://saxon.sf.net/" saxon:line-length="1000"/>

答案 1 :(得分:1)

您拥有多个处理器以相同格式生成输出的目标无可救药地被误导。如果你选择缩进输出,那就特别如此:规范将它完全留给实现如何进行缩进,只说目标是使其具有人类可读性。 (并在可以插入额外空格的位置设置约束。)

对不起,您不会发现Saxon的长篇属性列表令人满意的方式,但它完全符合规范的文字和精神。没有它,如果你有一个带有八个命名空间声明的元素,你可以很容易地获得一个长度为400个字符的行,我当然不认为它是人类可读的。

有许多原因可以从词汇上比较两个XML文档永远不会起作用。例如,属性可以采用不同的顺序。有两种比较XML的方法:使用&#34; Canonical XML&#34;将文档转换为规范形式。处理器,或者在树级别比较它们,例如使用XPath 2.0 deep-equal()函数。理想情况下(特别是如果您想知道差异的位置,而不仅仅是存在差异),请使用专业的XML比较工具,例如DeltaXML。

对于它的价值,当我们进行单元测试时,我们首先尝试对结果进行词汇比较。如果失败,我们解析两个文档并使用saxon:deep-equal()进行比较,这是deep-equal()函数的一种修改形式,可以很好地控制比较规则,例如:处理空格和处理命名空间。