Во-первых, отношение "равно" не может иметь такое имя.
«Равно» означает, что отношение является отношением эквивалентности. По определению любое отношение эквивалентности ~
должно быть:
Рефлексивный: x ~ x
.
Симметрично: если x ~ y
, то y ~ x
Переходный: если x ~ y
и y ~ z
, то x ~ z
.
Вот пример, показывающий, что предлагаемое отношение "равно" не является транзитивным:
x
is:
<a>
<c type="type-one" id="5675"/>
<c type="type-two" id="3423"/>
<c type="type-three" id="9088"/>
</a>
y
is:
<b>
<c type="type-one" id="5675"/>
<c type="type-two" id="3423"/>
<c type="type-four" id="1234"/>
</b>
z
is:
<b>
<c type="type-three" id="3333"/>
<c type="type-four" id="1234"/>
</b>
Теперь мы видим, что x ~ y
и y ~ z
. Однако очевидно, что это не так: x ~ z
При этом я называю отношение «совпадает», и оно расслаблено, а не «равно».
Вот решение проблемы с приведенной выше корректировкой:
Обратите внимание, что это нельзя выразить одним выражением XPath, поскольку XPath 1.0 (используемый в преобразовании XSLT 1.0) не имеет переменных диапазона.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/*">
<xsl:call-template name="matches">
<xsl:with-param name="pElem1" select="a"/>
<xsl:with-param name="pElem2" select="b"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="matches">
<xsl:param name="pElem1" select="/.."/>
<xsl:param name="pElem2" select="/.."/>
<xsl:variable name="vMisMatch">
<xsl:for-each select="$pElem1/c[@type = $pElem2/c/@type]">
<xsl:if test=
"$pElem2/c[@type = current()/@type and not(@id = current()/@id)]">1</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:copy-of select="not(string($vMisMatch))"/>
</xsl:template>
</xsl:stylesheet>
Когда это преобразование применяется к следующему XML-документу:
<t>
<a>
<c type="type-one" id="5675"/>
<c type="type-two" id="3423"/>
<c type="type-three" id="9088"/>
</a>
<b>
<c type="type-one" id="5675"/>
<c type="type-two" id="3423"/>
</b>
</t>
получен желаемый правильный результат:
true
Когда такое же преобразование применяется к этому XML-документу:
<t>
<a>
<c type="type-one" id="5675"/>
<c type="type-two" id="3423"/>
<c type="type-three" id="9088"/>
</a>
<b>
<c type="type-one" id="5675"/>
<c type="type-two" id="9876"/>
</b>
</t>
снова получен правильный результат:
false
person
Dimitre Novatchev
schedule
20.01.2013
a
иb
в первом примере могут быть равны, еслиa
имеет дочерний элемент<c type="type-three" id="9088"/>
, у которого нет соответствующего дочернего элементаb
??? Пожалуйста, отредактируйте вопрос и исправьте. Текущий пример противоречит понятию равенства. - person Dimitre Novatchev   schedule 20.01.2013<a><item key="one" value="foo"/><item key="two" value="one"/></a>, <b><item key="one" value="foo"/><item key="three" value="bar"/></b>, <c><item key="one" value="foo"/><item key="two" value="other"/></c>
, A «равно» B, B «равно» C, но A «не равно» C. Я ожидаю штрафа от полиции формальной логики. :-) - person adam.baker   schedule 21.01.2013