Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.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
Python 带有子路径的XPath谓词,使用lxml?_Python_Xml_Xpath_Lxml - Fatal编程技术网

Python 带有子路径的XPath谓词,使用lxml?

Python 带有子路径的XPath谓词,使用lxml?,python,xml,xpath,lxml,Python,Xml,Xpath,Lxml,我试图理解发送给我用于ACORD XML表单(保险中的通用格式)的XPath和XPath。他们发送给我的XPath是(为简洁起见被截断): 我遇到的麻烦是Python告诉我[InsuredOrPrincipalInfo/InsuredOrPrincipalRoleCd=“AN”]是一个无效谓词。我在中找不到任何可以识别此语法的地方,因此我可以修改此谓词以使其工作 有关于这个谓词选择什么的文档吗?还有,这是一个有效的谓词,还是有什么东西被弄坏了 可能相关: 我相信与我合作的公司是一家微软商店,所以

我试图理解发送给我用于ACORD XML表单(保险中的通用格式)的XPath和XPath。他们发送给我的XPath是(为简洁起见被截断):

我遇到的麻烦是Python告诉我
[InsuredOrPrincipalInfo/InsuredOrPrincipalRoleCd=“AN”]
是一个
无效谓词。我在中找不到任何可以识别此语法的地方,因此我可以修改此谓词以使其工作

有关于这个谓词选择什么的文档吗?还有,这是一个有效的谓词,还是有什么东西被弄坏了

可能相关:

我相信与我合作的公司是一家微软商店,所以这个XPath在C#或该堆栈中的其他语言中可能有效?我不完全确定

更新:

根据评论要求,这里有一些额外的信息

XML示例:

<ACORD>
  <InsuranceSvcRq>
    <HomePolicyQuoteInqRq>
      <PersPolicy>
        <PersApplicationInfo>
            <InsuredOrPrincipal>
                <InsuredOrPrincipalInfo>
                    <InsuredOrPrincipalRoleCd>AN</InsuredOrPrincipalRoleCd>
                </InsuredOrPrincipalInfo>
                <GeneralPartyInfo>
                    <Addr>
                        <Addr1></Addr1>
                    </Addr>
                </GeneralPartyInfo>
            </InsuredOrPrincipal>
        </PersApplicationInfo>
      </PersPolicy>
    </HomePolicyQuoteInqRq>
  </InsuranceSvcRq>
</ACORD>
代码示例(使用完整的XPath而不是代码段):

来自lxml导入etree的
>>
>>>tree=etree.fromstring(原始)
>>>树.查找('./InsuranceSvrq/HomePolicyQuoteInqRq/PersPolicy/PersApplicationInfo/InsuranceOrPrincipal[InsuranceOrPrincipalInfo/InsuranceOrPrincipalRolecd=“AN”]/GeneralPartyInfo/Addr/Addr1')
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
lxml.etree.\u Element.find(src/lxml/lxml.etree.c:39972)中的文件“lxml.etree.pyx”,第1409行
文件“/Library/Python/2.5/site packages/lxml-2.3-py2.5-macosx-10.3-i386.egg/lxml/_elementpath.py”,第271行,在find中
it=iterfind(元素、路径、名称空间)
iterfind中的文件“/Library/Python/2.5/site packages/lxml-2.3-py2.5-macosx-10.3-i386.egg/lxml/_elementpath.py”,第261行
选择器=\构建\路径\迭代器(路径,名称空间)
文件“/Library/Python/2.5/site packages/lxml-2.3-py2.5-macosx-10.3-i386.egg/lxml/_elementpath.py”,第245行,在构建路径迭代器中
selector.append(ops[token[0]](下一步,token))
文件“/Library/Python/2.5/site packages/lxml-2.3-py2.5-macosx-10.3-i386.egg/lxml/_elementpath.py”,第207行,在prepare_谓词中
引发语法错误(“无效谓词”)
SyntaxError:无效谓词

我认为你的例子非常好。我会检查lxmls XPath实现是否有一些文档化的限制或类似的限制。

您得到的XPath是完全正确的。也许将其嵌入Python会出现问题,在Python中需要使用Python转义约定来转义字符串中的双引号

./PersApplicationInfo/InsuredOrPrincipal
                 [InsuredOrPrincipalInfo/InsuredOrPrincipalRoleCd="AN"]
                     /GeneralPartyInfo/
此表达式存在一些问题

./PersApplicationInfo/InsuredOrPrincipal
                 [InsuredOrPrincipalInfo/InsuredOrPrincipalRoleCd='AN']
                     /GeneralPartyInfo
<ACORD>
    <InsuranceSvcRq>
        <HomePolicyQuoteInqRq>
            <PersPolicy>
                <PersApplicationInfo>
                    <InsuredOrPrincipal>
                        <InsuredOrPrincipalInfo>
                            <InsuredOrPrincipalRoleCd>AN</InsuredOrPrincipalRoleCd>
                        </InsuredOrPrincipalInfo>
                        <GeneralPartyInfo>
                            <Addr>
                                <Addr1></Addr1>
                            </Addr>
                        </GeneralPartyInfo>
                    </InsuredOrPrincipal>
                </PersApplicationInfo>
            </PersPolicy>
        </HomePolicyQuoteInqRq>
    </InsuranceSvcRq>
</ACORD>
<Addr1 />
  • 结尾的
    /
    字符使其在语法上无效
    。它标志着一个新的定位步骤的开始,但随后什么也没有发生

  • 正如Michael Kay博士所注意到的,Python中的嵌套引号可能存在问题

  • 建议的解决方案

    ./PersApplicationInfo/InsuredOrPrincipal
                     [InsuredOrPrincipalInfo/InsuredOrPrincipalRoleCd='AN']
                         /GeneralPartyInfo
    
    <ACORD>
        <InsuranceSvcRq>
            <HomePolicyQuoteInqRq>
                <PersPolicy>
                    <PersApplicationInfo>
                        <InsuredOrPrincipal>
                            <InsuredOrPrincipalInfo>
                                <InsuredOrPrincipalRoleCd>AN</InsuredOrPrincipalRoleCd>
                            </InsuredOrPrincipalInfo>
                            <GeneralPartyInfo>
                                <Addr>
                                    <Addr1></Addr1>
                                </Addr>
                            </GeneralPartyInfo>
                        </InsuredOrPrincipal>
                    </PersApplicationInfo>
                </PersPolicy>
            </HomePolicyQuoteInqRq>
        </InsuranceSvcRq>
    </ACORD>
    
    <Addr1 />
    
    在此表达式中,双引号替换为单引号。第二个更改是删除结尾的
    /
    字符

    更新:现在OP提供了一个更完整的代码示例,我能够验证实际使用的XPath表达式没有任何错误。以下是它与XSLT的验证:

    <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
     <xsl:template match="/*">
      <xsl:copy-of select=
      './InsuranceSvcRq/HomePolicyQuoteInqRq/PersPolicy
                     /PersApplicationInfo/InsuredOrPrincipal
                         [InsuredOrPrincipalInfo/InsuredOrPrincipalRoleCd="AN"]
                                                       /GeneralPartyInfo/Addr/Addr1'/>
     </xsl:template>
    </xsl:stylesheet>
    
    
    
    当此转换应用于提供的XML文档时

    ./PersApplicationInfo/InsuredOrPrincipal
                     [InsuredOrPrincipalInfo/InsuredOrPrincipalRoleCd='AN']
                         /GeneralPartyInfo
    
    <ACORD>
        <InsuranceSvcRq>
            <HomePolicyQuoteInqRq>
                <PersPolicy>
                    <PersApplicationInfo>
                        <InsuredOrPrincipal>
                            <InsuredOrPrincipalInfo>
                                <InsuredOrPrincipalRoleCd>AN</InsuredOrPrincipalRoleCd>
                            </InsuredOrPrincipalInfo>
                            <GeneralPartyInfo>
                                <Addr>
                                    <Addr1></Addr1>
                                </Addr>
                            </GeneralPartyInfo>
                        </InsuredOrPrincipal>
                    </PersApplicationInfo>
                </PersPolicy>
            </HomePolicyQuoteInqRq>
        </InsuranceSvcRq>
    </ACORD>
    
    <Addr1 />
    
    生成所需的正确结果

    ./PersApplicationInfo/InsuredOrPrincipal
                     [InsuredOrPrincipalInfo/InsuredOrPrincipalRoleCd='AN']
                         /GeneralPartyInfo
    
    <ACORD>
        <InsuranceSvcRq>
            <HomePolicyQuoteInqRq>
                <PersPolicy>
                    <PersApplicationInfo>
                        <InsuredOrPrincipal>
                            <InsuredOrPrincipalInfo>
                                <InsuredOrPrincipalRoleCd>AN</InsuredOrPrincipalRoleCd>
                            </InsuredOrPrincipalInfo>
                            <GeneralPartyInfo>
                                <Addr>
                                    <Addr1></Addr1>
                                </Addr>
                            </GeneralPartyInfo>
                        </InsuredOrPrincipal>
                    </PersApplicationInfo>
                </PersPolicy>
            </HomePolicyQuoteInqRq>
        </InsuranceSvcRq>
    </ACORD>
    
    <Addr1 />
    
    
    

    结论:问题要么在于Python代码的使用,要么(不太可能)使用的XPath引擎存在错误。

    更改
    树。查找
    树。XPath
    find
    findall
    以提供与ElementTree的其他实现的兼容性。要使用包含更高级功能的XPath表达式,请使用
    XPath
    方法、
    XPath
    类或
    XPathEvaluator

    例如:

    import io
    import lxml.etree as ET
    
    content='''\
    <ACORD>
      <InsuranceSvcRq>
        <HomePolicyQuoteInqRq>
          <PersPolicy>
            <PersApplicationInfo>
                <InsuredOrPrincipal>
                    <InsuredOrPrincipalInfo>
                        <InsuredOrPrincipalRoleCd>AN</InsuredOrPrincipalRoleCd>
                    </InsuredOrPrincipalInfo>
                    <GeneralPartyInfo>
                        <Addr>
                            <Addr1></Addr1>
                        </Addr>
                    </GeneralPartyInfo>
                </InsuredOrPrincipal>
            </PersApplicationInfo>
          </PersPolicy>
        </HomePolicyQuoteInqRq>
      </InsuranceSvcRq>
    </ACORD>
    '''
    tree=ET.parse(io.BytesIO(content))
    path='//PersApplicationInfo/InsuredOrPrincipal[InsuredOrPrincipalInfo/InsuredOrPrincipalRoleCd="AN"]/GeneralPartyInfo'
    result=tree.xpath(path)
    print(result)
    

    据我所知,lxml基本上是libxml2的一个接口,我找不到关于这两个接口的任何信息,因为它们都没有完整的实现。你能举一个XML示例,说明
    InsuredOrPrincipal[InsuredOrPrincipalInfo/insuredorprincipalecd=“an”]
    应该匹配吗,XPath规范确实指出谓词可以包含路径表达式,但引用非常模糊:
    PredicateExpr::='['Expr']'
    ,其中
    Expr
    可以包含任意关系表达式,包括
    PathExpr
    。字符串在单引号内,因此不需要转义。在使用XPath之前,我一直在修剪XPath的尾部
    /
    ,因为它会导致返回不正确的节点。我把它复制到这里时忘了把它取下来。我还用单引号将字符串括起来,尽管我尝试了两种方法来彻底解释。仍然抛出带有无效谓词的
    语法错误
    。规范中有关于这类谓词的文档吗?@Jack M。如果您提供完整的XPath表达式及其参与的代码,那么许多人会向您指出问题的确切原因。正如大家所指出的,您在questin中提供的XPath表达式片段是正确的——因此问题出在您没有向我们展示的代码中。@Jack M:我已经更新了我的答案