Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xslt 基于两个属性值的组合选择唯一节点_Xslt_Xpath - Fatal编程技术网

Xslt 基于两个属性值的组合选择唯一节点

Xslt 基于两个属性值的组合选择唯一节点,xslt,xpath,Xslt,Xpath,我有一些看起来像这样的XML: <Root> <Documents> <Document id="1"/> </Documents> <People> <Person id="1"/> <Person id="2"/> </People> <Links> <Link personI

我有一些看起来像这样的XML:

<Root>
    <Documents>
        <Document id="1"/>
    </Documents>
    <People>
        <Person id="1"/>
        <Person id="2"/>
    </People>
    <Links>
        <Link personId="1" documentId="1"/>
        <Link personId="1" documentId="1"/>
        <Link personId="2" documentId="1"/>
    </Links>
</Root>

我只想得到“Link”元素,它们具有“personId”和“documentId”的独特组合,因此这两个链接:

<Root>
    <Links>
        <Link personId="1" documentId="1"/>
        <Link personId="2" documentId="1"/>
    </Links>
</Root>

我该怎么做呢?我发现,虽然我觉得我的函数稍微复杂一些,可能不适用……我想我需要在某个地方使用key()函数


提前感谢。

您可以将多个选择器属性组合到XPath查询中,而不必只是单个属性=值对


您需要使用类似的方法过滤
s,其中
current()
函数返回您正在检查唯一性的
s

.[not(preceding-sibling::Link[@personId   = current()/@personId and
                              @documentId = current()/@documentId])]
前面的同级::轴用于查找早期的
元素,方括号中的部分用于检查匹配的ID号。包装整个表达式的
not()
表示,只有在前面没有匹配的同级项时,整个括号中的表达式才为真,即前面没有具有相同人员和文档ID的

我的XSLT知识已经过时了,所以我将把这部分留给您。我的想法是,首先查找所有链接,比如说,
//Link
,然后在第二步中使用上述XPath过滤它们。我很努力,但想不出任何方法可以一步完成这一切,因为这依赖于
current()
函数工作。

此样式表:

<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>
<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>
<Root>
    <Links>
        <Link personId="1" documentId="1"></Link>
        <Link personId="2" documentId="1"></Link>
    </Links>
</Root>

如果您不想检查是否存在此类文档或Person@id,则此样式表:

<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>
<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>
<Root>
    <Links>
        <Link personId="1" documentId="1"></Link>
        <Link personId="2" documentId="1"></Link>
    </Links>
</Root>

好的,优雅的。(+1). 我几乎得出了同样的结论。