Эта таблица стилей:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="kDocAndPeoById" match="Document|Person" use="@id"/>
<xsl:key name="kLinksByIds" match="Link"
use="concat(@personId,'++',@documentId)"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Documents|People|
Link[count(.|key('kLinksByIds',concat(@personId,'++',@documentId))[1])!=1
or not(key('kDocAndPeoById',@personId)/self::Person)
or not(key('kDocAndPeoById',@documentId)/self::Document)]"/>
</xsl:stylesheet>
Выход:
<Root>
<Links>
<Link personId="1" documentId="1"></Link>
<Link personId="2" documentId="1"></Link>
</Links>
</Root>
Если вас не интересует проверка, есть ли такой Document или Person @id, тогда эта таблица стилей:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="kLinksByIds" match="Link"
use="concat(@personId,'++',@documentId)"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Documents|People|
Link[count(.|key('kLinksByIds',concat(@personId,'++',@documentId))[1])!=1]"/>
</xsl:stylesheet>
Выход:
<Root>
<Links>
<Link personId="1" documentId="1"></Link>
<Link personId="2" documentId="1"></Link>
</Links>
</Root>