我正在尝试运行deep-equal function来比较2个节点序列。
对于我期望匹配的序列,唯一的区别是这里和那里的一些回车以及其中一个序列的附加ID
元素。
例如:
<body>
<section>
<p>that's a paragraph</p>
<p @class="p1">that's another paragraph</p>
</section>
</body>
和:
<body>
<section id="1">
<p id="2">that's a
paragraph</p>
<p @class="p1" id="3">that's another paragraph</p>
</section>
</body>
对我来说,这是一场比赛。
现在,deep-equal不喜欢回车和id。所以我一直在努力修改它以确保它仍然匹配。
使用remove-attributes-deep,我已经深度相等:
<xsl:function name="functx:deep-similar" as="xs:boolean">
<xsl:param name="seq1" as="item()*"/>
<xsl:param name="seq2" as="item()*"/>
<xsl:variable name="seq1-noId" select="functx:remove-attributes-deep($seq1,'id')"/>
<xsl:variable name="seq2-noId" select="functx:remove-attributes-deep($seq2,'id')"/>
<xsl:sequence select="every $i in 1 to max((count($seq1-noId), count($seq2-noId)))
satisfies deep-equal($seq1-noId[$i], $seq2-noId[$i])"/>
</xsl:function>
此代码基本上是来自sequence-deep-equal并且remove-attributes-deep之上的代码。
现在我想调整它以规范化空间。
如何对序列中每个节点的单个text()进行规范化,同时保留节点,以便在更新后我可以在它们上运行深度相等?我需要它在函数本身内部。
我无法删除文件,有些空格对我来说至关重要。
答案 0 :(得分:1)
我建议在与id
比较之前,定义一个执行转换(即文本值规范化和deep-equal
属性删除)的命名模式:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:variable name="t1">
<body>
<section>
<p>that's a paragraph</p>
<p class="p1">that's another paragraph</p>
</section>
</body>
</xsl:variable>
<xsl:variable name="t2">
<body>
<section id="1">
<p id="2">that's a
paragraph</p>
<p class="p1" id="3">that's another paragraph</p>
</section>
</body>
</xsl:variable>
<xsl:template name="main">
<xsl:variable name="nt1">
<xsl:apply-templates select="$t1" mode="normalize"/>
</xsl:variable>
<xsl:variable name="nt2">
<xsl:apply-templates select="$t2" mode="normalize"/>
</xsl:variable>
<xsl:value-of select="'deep-equal($t1, $t2): ', deep-equal($t1, $t2), '; deep-equal($nt1, $nt2): ', deep-equal($nt1, $nt2)"/>
</xsl:template>
<xsl:template match="@* | node()" mode="#all">
<xsl:copy>
<xsl:apply-templates select="@* , node()" mode="#current"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()" mode="normalize">
<xsl:value-of select="normalize-space()"/>
</xsl:template>
<xsl:template match="@id" mode="normalize"/>
</xsl:stylesheet>
如果您不希望所有模式的身份转换,您当然只能为命名模式定义它,即替换
<xsl:template match="@* | node()" mode="#all">
<xsl:copy>
<xsl:apply-templates select="@* , node()" mode="#current"/>
</xsl:copy>
</xsl:template>
通过
<xsl:template match="@* | node()" mode="normalize">
<xsl:copy>
<xsl:apply-templates select="@* , node()" mode="normalize"/>
</xsl:copy>
</xsl:template>