XSLT Identity Transformation而不更改输出

时间:2013-02-18 21:26:38

标签: xslt xslt-1.0

是否有可能进行xslt身份转换,绝对没有从源头改变?

当我使用以下模板时,输出中会更改ident和换行符,并且我不想对源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>

INPUT

<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>

3 个答案:

答案 0 :(得分:2)

不,你不能。输入和输出XML在它们生成相同XML Infoset的意义上将是“相同的”,但它们不一定是逐字节相同的,并且这不是XSLT可以控制的。

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

答案 1 :(得分:1)

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

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

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

答案 2 :(得分:1)

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

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

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

如果有问题的空白带有信息,你会想要重新审视词汇表的设计(这个空白很重要,这真的是个坏主意);如果仅仅是因为您希望属性值规范之间存在换行符,则可能需要编写自定义序列化程序以在输出中插入此类换行符和缩进。 (如果你的动机是避免混淆差异程序与空白差异,我的经验是你的选择是在变异之前规范化空白,或者在面对空白变化时获得一个更强大的差异程序。)祝你好运。 / p>