【问题标题】:XPath expression fails. (libxml2 in C) [closed]XPath 表达式失败。 (C 中的 libxml2)[关闭]
【发布时间】:2012-09-16 23:02:35
【问题描述】:

我在 C 程序中使用 libxml2 在 XML 文档中做一些事情。 现在...如果我查看以下 XPath,我会得到一个空结果。

/scheda_conservatore[1]/patrimonio_archivistico[1]/lower_list[@type='risorsa_informativa']/risorsa_informativa_nested[@id='037006-001-2012-ri002']

但是...如果我查找以下 XPAth,我会得到一个非空结果,其中包含即使从第一个也应该匹配的元素。

/scheda_conservatore[1]/patrimonio_archivistico[1]/lower_list/risorsa_informativa_nested[@id='037006-001-2012-ri002']

现在...如果我一步一步检查我的 XPath...

/scheda_conservatore[1] -> 非空节点集 /scheda_conservatore[1]/patrimonio_archivistico[1] -> 非空节点集 /scheda_conservatore[1]/patrimonio_archivistico[1]/lower_list[@type='risorsa_informativa'] -> 空节点集。

正如我之前所说,XML 文档确实包含一个有效路径,但此请求不匹配该路径。 更多:如果我让 jEdit 或其他支持 XPath 的编辑器为我解决 XPath 表达式,结果是一个非空节点集。

我要疯了。我看了数千次 XPath 表达式,肯定有什么非常不对劲的地方,至少在我眼里是非常隐蔽的,即使它在别人看来肯定很精彩。


更多... 以下只是询问“类型”属性而不查看它的值,给出了一个有效的结果。但值也是正确的。 /scheda_conservatore[1]/patrimonio_archivistico[1]/lower_list[@type]/risorsa_informativa_nested[@id='037006-001-2012-ri002']


这是较大 XML 文档的“导演剪辑版”

  <?xml version="1.0" encoding="iso-8859-1"?>
  <scheda_conservatore    anno_rilevazione="2012" stato="non-storicizzata">  
     <!-- scheda 2012 per Bologna -->  
     <patrimonio_archivistico> 
        <lower_list type="complesso_archivistico"> 
           <complesso_archivistico_nested id="037006-001-2012-ca001" inventariazione="n"> 
              <lower_list type="altro_luogo_collocazione"> 
                 <altro_luogo_collocazione_nested id="037006-001-2012-alc001"> 
                    <!-- altro luogo 1 per bologna 2012 -->  
                    <upper_list type="complesso_archivistico"> 
                       <upper ref="ca002"/>  
                       <upper ref="ca003"/> 
                    </upper_list>  
                    <ubicazione>sotterraneo da botola segreta</ubicazione>  
                    <bridge_list type="sede"> 
                       <bridge ref="s001"/> 
                    </bridge_list>  
                 </altro_luogo_collocazione_nested>  
              </lower_list>  
              <!-- complesso 1 per bologna 2012 -->  
              <identificazione> 
                 <denominazione>Archivi dei Comprensori della provincia di Bologna</denominazione>  
                 <lista_altre_denominazioni> 
                    <!-- Modificato -->  
                    <altra_denominazione>Archivi dei Comprensori bolognesi</altra_denominazione>  
                    <altra_denominazione>Archivi dei Comprensori felsinei</altra_denominazione> 
                 </lista_altre_denominazioni>  
                 <livello>Complesso di fondi, Superfondo</livello> 
              </identificazione>  
              <dati_giuridici> 
                 <tipologia>Pubblico</tipologia>  
                 <notificato_dichiarato presente="y"> 
                    <data>20100304T000000</data> 
                 </notificato_dichiarato> 
              </dati_giuridici>  
              <lower_list type="titolare"> 
                 <titolare_nested id="037006-001-2012-t001"> 
                    <!-- titolare 1 per bologna 2012 -->  
                    <upper_list type="complesso_archivistico"> 
                       <upper ref="ca001"/>  
                       <upper ref="ca002"/> 
                    </upper_list>  
                 </titolare_nested> 
              </lower_list> 
           </complesso_archivistico_nested>  
        </lower_list>  
        <lower_list type="risorsa_informativa"> 
           <risorsa_informativa_nested id="037006-001-2012-ri001"> 
              <bridge_list type="complesso_archivistico"> 
                 <bridge ref="ca001"/>  
                 <bridge ref="ca002"/> 
              </bridge_list>  
              <!-- risorsa 1 per bologna 2012 -->  
              <descrizione> 
                 <autore>CSR - Centro studi e ricerche</autore>  
                 <titolo>Atti degli uffici: inventario-mappa topografica del...</titolo>  
                 <anno indicativo="y">1986</anno>  
                 <qualifica> 
                    <opz pubbl="y">Strumenti di ricerca archivistici</opz> 
                 </qualifica>  
                 <scelta_multipla nome="standard"> 
                    <opz valore="AACR2"/>  
                    <opz valore="Altro">EAD</opz> 
                 </scelta_multipla>  
                 <descr_estrinseca>Dattiloscritto (relativo a: documentazione post 1945 conservata in Viale Martiri della Libert&amp;#x2026;)</descr_estrinseca> 
              </descrizione>  
              <lista_pubblicazioni> 
                 <pubblicazione> 
                    <edita presente="y">stampa</edita>  
                    <edita_stampa> 
                       <curatore/>  
                       <edito_in/>  
                       <luogo/>  
                       <data/>  
                       <pagine/>  
                       <sbn/>  
                       <note/> 
                    </edita_stampa>  
                    <url/>  
                    <ultima_consultazione>20120611T165400</ultima_consultazione>  
                    <nota>Nessuna nota</nota> 
                 </pubblicazione>  
                 <pubblicazione> 
                    <edita presente="y">web</edita>  
                    <edita_stampa/>  
                    <url>www.risorsainformativa.gov</url>  
                    <ultima_consultazione/>  
                    <nota>Nessuna nota web</nota> 
                 </pubblicazione> 
              </lista_pubblicazioni>  
              <informatizzazione presente="y"> 
                 <scelta_multipla nome="applicativi_utilizzati"> 
                    <!-- MODIFICATO!! -->  
                    <opz valore="Access (database)"/>  
                    <opz valore="Altro">eXtraWay</opz> 
                 </scelta_multipla>  
                 <partecipazione_sistemi_informativi presente="y"> 
                    <descrizione>x.dams</descrizione> 
                 </partecipazione_sistemi_informativi> 
              </informatizzazione> 
           </risorsa_informativa_nested>  
        </lower_list>  
        <lower_list type="intervento"> 
           <intervento_nested autor_sovraintendenza="y" id="037006-001-2012-i001" in_corso="y"> 
              <!-- intervento 1 per bologna 2012 -->  
              <descrizione>Restauro archivi dei comprensori della provincia di Bologna</descrizione>  
              <scelta_multipla nome="tipologia"> 
                 <opz valore="Riordino"/>  
                 <opz valore="Altro">Pulizia</opz> 
              </scelta_multipla>  
              <avvio>20111101T000000</avvio>  
              <conclusione_prevista>20120701T000000</conclusione_prevista>  
              <conclusione_effettiva/>  
              <autore/>  
              <promotore/>  
              <scelta_multipla nome="standard_descrittivi"> 
                 <opz valore="ISAD"/>  
                 <opz valore="Altro">Descrizione altro standard descrittivo</opz> 
              </scelta_multipla>  
              <informatizzazione presente="y"> 
                 <scelta_multipla nome="applicativo_utilizzato"> 
                    <opz valore="Access (database)"/>  
                    <opz valore="Altro">eXtraWay</opz> 
                 </scelta_multipla>  
                 <partecipazione_sistemi_informativi presente="y"> 
                    <descrizione>x.dams</descrizione> 
                 </partecipazione_sistemi_informativi> 
              </informatizzazione>  
              <bridge_list type="complesso_archivistico"> 
                 <bridge ref="ca001"/> 
              </bridge_list> 
           </intervento_nested>  
        </lower_list>  
        <note/> 
     </patrimonio_archivistico>  
     <note/>
     <?xw-meta Dbms="ExtraWay" DbmsVer="24.3.1" OrgNam="3D Informatica" OrgVer="1.0" Classif="1.0" ManGest="3.1" ManTec="0.0.4" DocType="" InsUser="admin" InsTime="20120910175739" ModUser="rtirabassi" ModTime="20120925145347"?>
     <?xw-crc key32=e324f581-406521b5?>

  </scheda_conservatore>

好的,现在问题是假设另一个方面。可能我必须“关闭”这个并传递给另一个问题。

原始(更广泛的)XML 文档上的 XPath 是正确的,现在我知道问题出在哪里,但不知道如何解决。

  • 如果我只在 XML 文档上执行一次 XPath 表达式,我就有了预期的结果;
  • 如果我在同一个 XML 文档上执行相当大的 XPath 序列,复杂的 XPath(包含与属性值有关的条件)会失败(只有那些);

所以我看了一下我们是如何实现 XPath 评估的,发现 XPathContext 从未被释放。所以我更改了代码,以便在每次 XPath 评估后释放上下文并每次都创建一个新的,但是......没有任何变化。

有什么想法吗?

【问题讨论】:

  • 是的,正如我所说,用 XPath 解析器(带有适当插件的 jEdit)处理的同一个 XML 文档给出了一个有效的结果,这意味着,第一个 XPath 表达式给我没有有效的结果一个 C++ 程序在其他场景(PHP、Java...)中给出一个有效的结果
  • 您能否发布您要匹配的完整的lower_list 标签 XML(包括属性和内容)?
  • 您的文档中有命名空间吗?
  • 您说:第一个在 C++ 程序中没有给出有效结果的 XPath 表达式在其他场景(PHP、Java...)中给出了有效结果。因此,您的 XPath 处理器中似乎存在错误。
  • Hem... 我的 XPath 处理器来自 libmxl2,如果出现错误,我该怎么办?更多:如果我也使用在 Windows 和 Linux 中编译的代码进行测试,就会出现问题,所以 lixml2 都失败了。

标签: c++ c xpath libxml2


【解决方案1】:

XPath 工作正常。您正在寻找@id='037006-001-2012-ri002,属性值为037006-001-2012-ri001。将xml更改为ri002匹配后,libxml返回正确的nodesetval。

如果它不能真正解决问题:也许id 属性被以特殊方式处理?尝试将其更改为idx。见Java XML DOM: how are id Attributes special?

【讨论】:

  • 确认了同样的事情,例如 XML 有 ri001,xpaths 指定 ri002。将 xpaths 更改为 ri002 具有问题返回结果中提到的所有表达式。
  • 我的错:原始 XML 文件超过 150KB,我无法将其添加到原始消息中(最大字符数为 30000)。在 cut & past 期间,我删除了与我之前所做的样本匹配的元素。我会尝试以不同的方式切割它。注意:我已经知道 XPath 是正确的(根据 XML 的内容),我只说,正如 Michale Key 所做的那样,libxml2 的 C 实现(Win 和 Linux)无法解析这个 XPath,而同样,在 Java 中,在 PHP 和其他中,都可以正常工作。
  • Gate,所以你建议它在一个大文件上失败并通过一个小文件?因为我们在(您的)一个小文件上进行了尝试。因此,请尝试划分 150KB,直到找到一个最小的违规示例以向 libxml 提交错误报告。你的应用程序在你发布的一个小例子上失败了吗?所以我宁愿在你的应用程序中搜索一个错误。当我在家时,我将在您的(更正的 ri001->ri002)文件上附加一个成功使用 xpath 表达式的小型 c 程序。
  • 这里是主题。无论文件有多大或多小,但如果我评估一个广泛的 XPath 列表,当测试包含属性的条件时,它会失败。如果我跳过所有先前的测试并仅评估该路径,则结果是正确的,因此... ...评估方法的大量使用方式一定有什么问题。查看 XPath 上下文,每次都创建为新的,但没有结果。
【解决方案2】:

好的,找到问题。 很抱歉这个误报。 libxml2 可以正常工作,但在 XPath 评估周期期间,XML 文档发生了变化,这改变了场景,导致我相信 XPath 处理器出现故障。 深度调试会话向我们展示了其他问题,只有具有属性条件(但不是最后一个条件)的 XPath 表达式失败。这促使我们找到了解决方案。 我的错。对不起。

【讨论】:

  • 好的,我将问题标记为关闭/删除,因为标题问题不成立。无论如何,我想我们帮助了您,您可能会接受“XPath 工作正常”的答案。
  • 我认为我必须接受一个有效的答案,因为故障都是我的(确实是我的一位同事),并且 XPath 工作正常。
  • 别担心 :) 很高兴您解决了问题并且您向我们解释了一切。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多