【问题标题】:Selecting an XPath child node without the parent namespace选择没有父命名空间的 XPath 子节点
【发布时间】:2016-07-20 22:47:15
【问题描述】:

我不经常使用 XML,也从未使用过 XPath。我正在尝试使用 XPath 解析使用 python/lxml 的 xml 文档。 lxml 依赖于 libxml2,因此我无法访问 XPath 2.0 功能。我正在尝试使用客户端提供的不包含命名空间的 XPath 列表来执行此操作。

如果有帮助,这些是加拿大房地产协会的 RETS 服务器响应。他们的文档在这里:http://www.crea.ca/wp-content/uploads/2016/02/DDFDataFeedTechnicalDoc-2016-3.pdf

路径的格式如下(还有很多):

Building/SizeInterior
Land/SizeTotal

父元素具有命名空间“urn:CREA.Search.Property”,如以下示例响应所示:

<?xml version="1.0" encoding="UTF-8"?>
<RETS ReplyCode="0" ReplyText="Operation successful">
   <COUNT Records="1" />
   <RETS-RESPONSE xmlns="urn:CREA.Search.Property">
      <Pagination>
         <TotalRecords>1</TotalRecords>
         <Limit>100</Limit>
         <Offset>1</Offset>
         <TotalPages>1</TotalPages>
         <RecordsReturned>1</RecordsReturned>
      </Pagination>
      <PropertyDetails ID="XXXXXXXXXX" LastUpdated="Sun, 12 Jun 2016 14:21:20 GMT">
         <Building>
            <SizeInterior />
            <Type>No Building</Type>
            <UtilityWater>Private Utility</UtilityWater>
         </Building>
         <Land>
            <SizeTotal>0.28 ac|under 1 acre</SizeTotal>
            <SizeTotalText>0.28 ac|under 1 acre</SizeTotalText>
            <AccessType>Easy access</AccessType>
            <Acreage>false</Acreage>
            <SizeIrregular>0.28</SizeIrregular>
         </Land>
      </PropertyDetails>
   </RETS-RESPONSE>
</RETS>

如果可能的话,我需要能够在不修改 XPath 的情况下抓取这些元素。

到目前为止,我的发现似乎表明,即使命名空间仅在父元素上明确指定,我也需要为路径中的每个子元素指定是否只有在我处理它们以在每个元素之前包含命名空间。

这是正确的还是有更清洁的方法?这让我觉得很混乱:如果孩子们没有明确分配给他们的命名空间,为什么 XPath 必须 明确说明它?

我想我错过了什么。

【问题讨论】:

  • 元素从其父元素继承命名空间。
  • @choroba,我知道。我不明白为什么需要为 XPath 中的每个孩子声明继承的命名空间。既然我们知道命名空间是在文档中继承的,为什么我不能指定父元素包含命名空间而子元素不包含命名空间的路径(即 xpath 会假定继承)。从我在网上可以找到的,这似乎是不可能的,但它让我觉得很奇怪。所以我想我会问。
  • 有可能:&lt;n:b xmlns:n="http://uri"&gt;&lt;c/&gt;&lt;/n:b&gt;。现在,//c 找到 c,即使其父命名空间是 n
  • @choroba,它似乎对我不起作用 :( 例如,这有效:tree.xpath('p:RETS-RESPONSE/p:PropertyDetails/p:Land', namespaces={'p': 'urn:CREA.Search.Property'}) 但这不起作用:tree.xpath('p:RETS-RESPONSE/p:PropertyDetails//Land', namespaces={'p': 'urn:CREA.Search.Property'})
  • 同样,tree.xpath('//Land') 也不起作用。

标签: xml xpath namespaces


【解决方案1】:

您对您的技术限制没有说太多。如果您能够使用 XPath 2.0 处理器,那么您应该能够将“元素和类型的默认命名空间”定义为 urn:CREA.Search.Property,并且使用像 Building/SizeInterior 这样的无前缀名称的路径然后将元素名称视为在此命名空间。

(XPath 不将 n:aaa/bbb 视为含义 n:aaa/n:bbb 的原因是,将无命名空间元素 bbb 作为命名空间元素 n:aaa 的子元素是非常合理的。

【讨论】:

  • 我对您的回复感到非常兴奋,然后意识到我正在使用 lxml,它依赖于不支持 XPath 2.0 的 libxml2。我会将其添加到原始问题中。
猜你喜欢
  • 1970-01-01
  • 2010-10-06
  • 1970-01-01
  • 1970-01-01
  • 2012-11-10
  • 1970-01-01
  • 1970-01-01
  • 2012-06-24
  • 1970-01-01
相关资源
最近更新 更多