2

是否可以进行 xslt 身份转换,其中从源头绝对没有任何变化?

当我使用以下模板时,输出中的标识和换行符发生了变化,我不想对源 xml 进行任何更改。

XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>  
</xsl:template>

输入

<S:Envelope
  xmlns:S="http://www.w3.org/2003/05/soap-envelope" 
  xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
  xmlns:f123="http://www.fabrikam123.example/svc53">
  <S:Header>
    <wsa:MessageID>
      uuid:aaaabbbb-cccc-dddd-eeee-wwwwwwwwwww
    </wsa:MessageID>
    <wsa:RelatesTo>
      uuid:aaaabbbb-cccc-dddd-eeee-ffffffffffff
    </wsa:RelatesTo>
    <wsa:To S:mustUnderstand="1">
      http://business456.example/client1
    </wsa:To>
    <wsa:Action>http://fabrikam123.example/mail/DeleteAck</wsa:Action>
  </S:Header>
  <S:Body>
    <f123:DeleteAck/>
  </S:Body>
</S:Envelope>

输出

<?xml version="1.0" encoding="UTF-8"?><S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:f123="http://www.fabrikam123.example/svc53">
  <S:Header>
    <wsa:MessageID>
      uuid:aaaabbbb-cccc-dddd-eeee-wwwwwwwwwww
    </wsa:MessageID>
    <wsa:RelatesTo>
      uuid:aaaabbbb-cccc-dddd-eeee-ffffffffffff
    </wsa:RelatesTo>
    <wsa:To S:mustUnderstand="1">
      http://business456.example/client1
    </wsa:To>
    <wsa:Action>http://fabrikam123.example/mail/DeleteAck</wsa:Action>
  </S:Header>
  <S:Body>
    <f123:DeleteAck/>
  </S:Body>
</S:Envelope>
4

3 回答 3

2

你不能。输入和输出 XML 将是“相同的”,因为它们生成相同的 XML 信息集,但它们不一定是逐字节相同的,这不是 XSLT 可以控制的。

你为什么需要这个?如果您想轻松比较 XML 文档,请考虑使用XML Canonicalization。许多 XML 库都有生成规范 XML 的方法,xmllint命令行工具可以轻松地从文件中生成它。

于 2013-02-18T22:01:22.837 回答
1

XSLT 处理器的默认行为是在输入中保留空格,而我刚刚测试的处理器的行为与规范一致。

但是有问题的空格是输入文本节点中的空格。

start-tags 中的属性值规范之间的空白,以及文档的 prolog 和 epilog 中的项目(例如注释和处理指令)之间的空白不是文本节点,并且不受保留空间设置的影响。事实上,该空白也不是 XPath 数据模型的一部分,因此处理器几乎无法合法地保留它。

如果有问题的空格包含信息,您将需要重新审视词汇表的设计(让空格很重要真的是个坏主意);如果只是您希望在属性值规范之间有换行符,您可能需要编写一个自定义序列化程序来在输出中插入这样的换行符和缩进。(如果您的动机是避免将 diff 程序与空白差异混淆,我的经验是您的选择是在 diff 之前对空白进行规范化,或者在面对空白变化时获得一个更加健壮的 diff 程序。)祝您好运。

于 2013-02-18T21:43:51.290 回答
1

一般来说,不可能 100% 确信您将完全改变所有内容,因为 xslt 数据模型根本不会保留解析中的所有信息。例如,如果输入包含&#x3C;,则输出可能包含&lt;. 类似地,不保留 CDATA 部分 - 相邻的文本节点(CDATA 部分和普通文本模式)在解析时合并为一个,虽然您可以将处理器配置为使用 CDATA 来处理某些元素的内容,但您不能简单地将它们保留为他们是。

还有其他问题,例如数据模型不区分<foo></foo>和- 它们都表示相同的空元素,<foo/>并且<foo />输入中的任何一个都可以由输出中的任何一个表示。并且在您的示例中,开始标记内的属性之间的空白不会被保留。

但当然,这些差异都是 XML 工具不应该关心的所有事情,因为它们是表示完全相同的信息集的不同方式。

于 2013-02-18T21:32:54.890 回答