【问题标题】:How to get elements with specific values in a XML using regular expression? [duplicate]如何使用正则表达式在 XML 中获取具有特定值的元素? [复制]
【发布时间】:2019-03-21 14:03:32
【问题描述】:

我有这段 xml 字符串。

<?xml version="1.0" encoding="UTF-8"?>
<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:libraries="http://www.ibm.com/websphere/appserver/schemas/5.0/libraries.xmi">
  <libraries:Library xmi:id="Library_1382473016602" name="sfi_lib" isolatedClassLoader="false">
    <classPath>${HOME_SFI_LIB}/sfi_com_sqw_java.jar</classPath>
  </libraries:Library>
  <libraries:Library xmi:id="Library_1528914932212" name="sfi_lib_server" isolatedClassLoader="false">
    <classPath>${HOME_SFI_LIB}/jasper/jasperreports-5.6.0.jar</classPath>
    <classPath>${HOME_SFI_LIB}/jasper/jasperreports-fonts-3.7.4.jar</classPath>
    <classPath>${HOME_SFI_LIB}/commons/commons-beanutils-1.8.2.jar</classPath>
    <classPath>${HOME_SFI_LIB}/commons/commons-collections-3.2.1.jar</classPath>
    <classPath>${HOME_SFI_LIB}/commons/commons-digester-2.1.jar</classPath>
    <classPath>${HOME_SFI_LIB}/commons/commons-discovery-0.2.jar</classPath>
    <classPath>${HOME_SFI_LIB}/commons/commons-logging-1.1.1.jar</classPath>
    <classPath>${HOME_SFI_LIB}/commons/xml-apis.jar</classPath>
    <classPath>${HOME_SFI_LIB}/commons/iText-2.1.7.jar</classPath>
    <classPath>${HOME_SFI_LIB}/jasper/barbecue-1.5-beta1.jar</classPath>
    <classPath>${HOME_SFI_LIB}/bouncycastle/bcprov-jdk15-1.45.jar</classPath>
    <classPath>${HOME_SFI_LIB}/bouncycastle/bcmail-jdk15-1.45.jar</classPath>
    <classPath>${HOME_SFI_LIB}/bouncycastle/bctsp-jdk14-1.45.jar</classPath>
    <classPath>${HOME_SFI}/sfi_arquivos/templates</classPath>
    <classPath>${HOME_SFI_LIB}/sfi_framework_java.jar</classPath>
    <classPath>${HOME_SFI_LIB}/sfi_adm_ama_java.jar</classPath>
    <classPath>${HOME_SFI_LIB}/sfi_adm_gce_java.jar</classPath>
    <classPath>${HOME_SFI_LIB}/sfi_adm_gdl_java.jar</classPath>
    <classPath>${HOME_SFI_LIB}/sfi_adm_prt_java.jar</classPath>
    <classPath>${HOME_SFI_LIB}/sfi_com_acg_java.jar</classPath>
    <classPath>${HOME_SFI_LIB}/sfi_com_sca_java.jar</classPath>
    <classPath>${HOME_SFI_LIB}/sfi_com_tge_java.jar</classPath>
    <classPath>${HOME_SFI_LIB}/sfi_com_utl_java.jar</classPath>
    <classPath>${HOME_SFI_LIB}/sfi_ext_sge_java.jar</classPath>
  </libraries:Library>
</xmi:XMI>

我要做的是获取以${HOME_SFI_LIB}/sfi_ 开头的元素的值。 我正在使用re python 的模块来完成这项工作。我当前的代码仅按标签classPath 过滤,但这还不够。我目前使用的正则表达式:

re.findall('<classPath>(.*?)</classPath>', xml)

有人可以帮助我改进我的 RE 以过滤以 ${HOME_SFI_LIB}/sfi_ 开头的元素,例如节点 &lt;classPath&gt;${HOME_SFI_LIB}/sfi_adm_gce_java.jar&lt;/classPath&gt;

【问题讨论】:

  • XML 和正则表达式不是好朋友。使用解析器,它更简单、更快且更易于维护。
  • @Toto 虽然我同意链接的帖子直接解决这个问题,但我不会说它回答它。对于特定于 python 的用例,可能有更好的重复

标签: python regex xml


【解决方案1】:

正如this post 著名指出的那样,最好使用lxml 等xml 解析器来浏览xml、html 和xhtml 等语言:

from lxml import etree

with open('your_file.xml') as fh:
    tree = etree.parse(fh)

# Now you have an elementTree instance that you can search tags with
# we can use a selector here to return a list
class_paths = tree.xpath('//classPath')

for c in class_paths:
    if '${HOME_SFI_LIB}/sfi_' in c.text:
        # rest of your code

虽然您可能会争辩说,对于一个简单的 xml 文档,正则表达式方法可以工作,但一般来说,树使这个过程更容易扩展到更大和更复杂的文档

编辑

如果你不能pip install lxmlxml 包是内置的,并且功能非常相似

from xml.etree import ElementTree as ET

with open('your_file.xml') as fh:
    tree = ET.parse(fh)

for element in tree.iterfind('.//classPath'):
    if '${HOME_SFI_LIB}/sfi_' in element.text:
        # rest of your code

【讨论】:

  • 问题是:我无法在我正在工作的服务器中安装任何库。这就是我尝试使用纯 python 的原因
  • 那么 xml.etree 包应该做得很好,它是一个内置的。我会编辑我的答案
猜你喜欢
  • 2018-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-16
  • 2013-04-20
  • 2012-01-16
  • 1970-01-01
  • 2018-07-27
相关资源
最近更新 更多