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
Xml 我可以让xpath搜索更快吗?_Xml_Xpath_Php 5.2 - Fatal编程技术网

Xml 我可以让xpath搜索更快吗?

Xml 我可以让xpath搜索更快吗?,xml,xpath,php-5.2,Xml,Xpath,Php 5.2,找到所有 是上下文元素的后代 具有auto属性 最高级别(在self和上下文元素之间没有具有auto属性的祖先) 因此,如果上下文节点是a,则应返回c和e 我已经在我的php类中实现了它: $tempId='XDFAY69LA'; $this->setAttribute('tempId',$tempId); $path=“../\*[@auto and not(祖先:\*[@auto and祖先::\*[@tempId='$tempId']])”; $ar=$this->getElementsB

找到所有

  • 是上下文元素的后代
  • 具有
    auto
    属性
  • 最高级别(在self和上下文元素之间没有具有
    auto
    属性的祖先)
  • 因此,如果上下文节点是
    a
    ,则应返回
    c
    e

    我已经在我的php类中实现了它:

    $tempId='XDFAY69LA';
    $this->setAttribute('tempId',$tempId);
    $path=“../\*[@auto and not(祖先:\*[@auto and祖先::\*[@tempId='$tempId']])”;
    $ar=$this->getElementsByXPath($path);
    $this->removeAttribute('tempId');
    
    但是我发现这个查询很慢,也许,因为查询太复杂了,有没有更好的方法


    我写了一个测试,请看一下:


    我想把它简化一点

    $path=".//*[@auto and not(ancestor::*[@auto and not(@tempId='$tempId'))]";
    
    “祖先::*[@tempId='$tempId']”

    “不是(@tempId='$tempId')”



    //编辑内容:从XPath开始删除冗长的内容:

     .//*[@auto and not(ancestor::*[@auto and ancestor::*[@tempId='$tempId']])]
    
    那么:

     .//*[@auto and not(ancestor::*[@auto][ancestor::*[@tempId='$tempId']])]
    
    甚至

     .//*[@auto and count(ancestor::*[@auto][ancestor::*[@tempId='$tempId']])=0]
    
    使用

    .//*[@auto and $tempId = ancestor::*[@auto][1]/@tempId]
    
    <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output omit-xml-declaration="yes" indent="yes"/>
    
     <xsl:template match="a">
       <xsl:variable name="tempId" select="@tempId"/>
    
         <xsl:copy-of select=
          ".//*[@auto and $tempId = ancestor::*[@auto][1]/@tempId]"/>
     </xsl:template>
    </xsl:stylesheet>
    
    <root>
        <a auto="1" tempId="current">
            <b>
                <c auto="1">
                    <d auto="1"></d>
                </c>
            </b>
            <e auto="1">
                <f>
                    <g auto="1"></g>
                </f>
            </e>
        </a>
    </root>
    
    <c auto="1">
       <d auto="1"/>
    </c>
    <e auto="1">
       <f>
          <g auto="1"/>
       </f>
    </e>
    
    <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:key name="kfirstDescendents" match="*[@auto]"
      use="generate-id(ancestor::*[@auto][1])"/>
    
     <xsl:template match="a">
         <xsl:copy-of select=
          "key('kfirstDescendents', generate-id())"/>
     </xsl:template>
    </xsl:stylesheet>
    
    这将选择具有
    auto
    属性且其具有
    auto
    属性的第一个祖先也具有与上下文节点的
    tempId
    属性值相同的
    tempId>属性的(上下文节点的)所有子代元素(后者存储在
    $tempId
    变量中)

    这里我们假设没有两个不同的元素具有相同的
    tempId
    属性值

    基于XSLT的快速验证

    .//*[@auto and $tempId = ancestor::*[@auto][1]/@tempId]
    
    <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output omit-xml-declaration="yes" indent="yes"/>
    
     <xsl:template match="a">
       <xsl:variable name="tempId" select="@tempId"/>
    
         <xsl:copy-of select=
          ".//*[@auto and $tempId = ancestor::*[@auto][1]/@tempId]"/>
     </xsl:template>
    </xsl:stylesheet>
    
    <root>
        <a auto="1" tempId="current">
            <b>
                <c auto="1">
                    <d auto="1"></d>
                </c>
            </b>
            <e auto="1">
                <f>
                    <g auto="1"></g>
                </f>
            </e>
        </a>
    </root>
    
    <c auto="1">
       <d auto="1"/>
    </c>
    <e auto="1">
       <f>
          <g auto="1"/>
       </f>
    </e>
    
    <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:key name="kfirstDescendents" match="*[@auto]"
      use="generate-id(ancestor::*[@auto][1])"/>
    
     <xsl:template match="a">
         <xsl:copy-of select=
          "key('kfirstDescendents', generate-id())"/>
     </xsl:template>
    </xsl:stylesheet>
    
    性能不能仅在XPath表达式中改进,效率低下是因为必须使用
    /
    XPath伪运算符

    如果使用XSLT,则可以使用键获得有效的解决方案

    .//*[@auto and $tempId = ancestor::*[@auto][1]/@tempId]
    
    <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output omit-xml-declaration="yes" indent="yes"/>
    
     <xsl:template match="a">
       <xsl:variable name="tempId" select="@tempId"/>
    
         <xsl:copy-of select=
          ".//*[@auto and $tempId = ancestor::*[@auto][1]/@tempId]"/>
     </xsl:template>
    </xsl:stylesheet>
    
    <root>
        <a auto="1" tempId="current">
            <b>
                <c auto="1">
                    <d auto="1"></d>
                </c>
            </b>
            <e auto="1">
                <f>
                    <g auto="1"></g>
                </f>
            </e>
        </a>
    </root>
    
    <c auto="1">
       <d auto="1"/>
    </c>
    <e auto="1">
       <f>
          <g auto="1"/>
       </f>
    </e>
    
    <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:key name="kfirstDescendents" match="*[@auto]"
      use="generate-id(ancestor::*[@auto][1])"/>
    
     <xsl:template match="a">
         <xsl:copy-of select=
          "key('kfirstDescendents', generate-id())"/>
     </xsl:template>
    </xsl:stylesheet>
    
    
    
    此转换产生与第一次相同的结果,并且在包含许多嵌套元素且具有
    auto
    属性的文档上大大加快


    如果完全排除使用XSLT,那么使用哈希表(对不起,我不知道PHP)可以达到与XSLT键相同的效果.

    非常感谢,但我认为这一个与我的不一样,也不是有效的xpath表达式。我是盲人。如果“a”的祖先具有“@auto”属性,则我的代码不匹配,对不起。请放心,我在这个问题上也犯了很多错误。谢谢。好问题,+1。有关较短的xpath表达式和muc的演示,请参阅我的答案h使用XSLT和键实现更快的解决方案。如果禁止使用XSLT,可以使用哈希表实现类似的解决方案。非常感谢,这教会了我一种新的xpathYeah!我喜欢你的表达式,尽管它似乎没有像你说的那样提高速度。我没有使用XSLT,但我认为我需要了解它以及你对哈希表的建议现在,感谢您的回复!@fclddcn:我从来没有说过表达式是快的——相反,我说它很慢,而且获得更快执行的唯一方法是通过缓存(索引、xslt键、哈希表等)。我明白了,很抱歉我的英语不好,我的意思是“和您说的一样”: