tree = etree.fromstring(bytes(xml,encoding ='utf-8'))TypeError:没有字符串参数的编码

问题描述 投票:0回答:6

我想编写一个函数,使我可以提取属性“ fmc”的值和“标签”部分中的文本。我想使用正则表达式解决方案。

<?xml version = "1.0" encoding="UTF-8" standalone="yes" ?>
<corpus>
    <ver id="18" etude="EC1_Elec" elec="oui" niveau="1" critere="1.3" type="discours">
        <part code="EC1_Elec_IW04_0">Ça existe sur des gros parcs Hlm mais c'est macro.</part>
    </ver>
    <ver id="30" etude="EC1_Elec" elec="oui" niveau="2" critere="" origine="IW" type="discours" fmc="motives">
        <part code="EC1_Elec_IW01_0">Avant 75 on n'a pas isolé puis après, au fur et à mesure des règlementations.</part>
    </ver>
    <ver id="54" etude="EC1_Elec" elec="oui" niveau="1" critere="" origine="IW" type="discours" fmc="condition">
        <part code="EC1_Elec_IW10_0">Le deuxième boitier, il est où ? s'il y en a un qui est à l'intérieur et qui remplace un bout de l'isolation, il est caché OK.</part>
    </ver>
    <ver id="897" etude="EC3_Elec" elec="oui" niveau="4" critere="4.1" origine="TR" type="discours" fmc="obstacle">
        <part code="EC3_Elec_TR2_1">Avec l'économie d'énergie, on va imposer de plus en plus d'automatismes,</part>
        <iwer>Çava influencer la demande pour ce type de solution c'est ça ?</iwer>
        <part code="EC3_Elec_TR2_1">Je pense oui</part>
    </ver>
</corpus>

因此我已根据上述答案修改了此功能以适合我的数据

代码

def review_extractor(xml, category='verbatim', do_lower=False):
    """
    Extract review and label
    """
    # use lxml...

    # parse the xml snippet into an object tree
    tree = etree.fromstring(bytes(xml, encoding='utf-8'))
    # find all elements that have "fmc" attribute
    for e in tree.findall(".//*[@fmc]"):
        label = e.xpath("./@fmc")[0]
        for c in e.getchildren("./part"):
            # print value of "fmc" attribute and text of child element
            print(f"{label:15}{c.text}")
            # 
        return label, c.text

因此,对于我的示例,该函数应返回此值(在标签之前进行检查):

Label      review_text
motivation Avant 75 on n'a pas isolé puis après, au fur et à mesure des règlementations.

condition Le deuxième boitier, il est où ? s'il y en a un qui est à l'intérieur et qui remplace un bout de l'isolation, il est caché OK.

obstacle Avec l'économie d'énergie, on va imposer de plus en plus d'automatismes,

obstacle Je pense oui

python regex xml xml-parsing
6个回答
1
投票

[我意识到您明确要求使用正则表达式解决方案,但作为替代方案,这里使用的是使用内置于xml解析器中的python之一,特别是xml.etree.ElementTree

xml.etree.ElementTree

输出为

xml_string = """<?xml version = "1.0" encoding="UTF-8" standalone="yes" ?>
<corpus>
    <ver id="18" etude="EC1_Elec" elec="oui" niveau="1" critere="1.3" type="discours">
        <part code="EC1_Elec_IW04_0">Ça existe sur des gros parcs Hlm mais c'est macro.</part>
    </ver>
    <ver id="30" etude="EC1_Elec" elec="oui" niveau="2" critere="" origine="IW" type="discours" fmc="motives">
        <part code="EC1_Elec_IW01_0">Avant 75 on n'a pas isolé puis après, au fur et à mesure des règlementations.</part>
    </ver>
    <ver id="54" etude="EC1_Elec" elec="oui" niveau="1" critere="" origine="IW" type="discours" fmc="condition">
        <part code="EC1_Elec_IW10_0">Le deuxième boitier, il est où ? s'il y en a un qui est à l'intérieur et qui remplace un bout de l'isolation, il est caché OK.</part>
    </ver>
    <ver id="897" etude="EC3_Elec" elec="oui" niveau="4" critere="4.1" origine="TR" type="discours" fmc="obstacle">
        <part code="EC3_Elec_TR2_1">Avec l'économie d'énergie, on va imposer de plus en plus d'automatismes,</part>
        <iwer>Çava influencer la demande pour ce type de solution c'est ça ?</iwer>
        <part code="EC3_Elec_TR2_1">Je pense oui</part>
    </ver>
</corpus>"""

import xml.etree.ElementTree as ET
tree = ET.fromstring(xml_string)

for i in tree.findall('ver'):
    fmc = i.attrib.get("fmc")
    if fmc is None:
        continue
    for p in i.findall("part"):
        print(fmc, p.text)

如果要使用xpath表达式,则可以稍微简化一下

motives Avant 75 on n'a pas isolé puis après, au fur et à mesure des règlementations.
condition Le deuxième boitier, il est où ? s'il y en a un qui est à l'intérieur et qui remplace un bout de l'isolation, il est caché OK.
obstacle Avec l'économie d'énergie, on va imposer de plus en plus d'automatismes,
obstacle Je pense oui

0
投票

尝试这个for i in tree.findall('ver[@fmc]'): for p in i.findall('part'): print(i.attrib['fmc'], p.text)


0
投票

您可以尝试正则表达式:

/fmc(.*?)+=(.*?)+\"(.+?)\"/g

如图所示<([a-zA-Z0-9]+)[^\/]*?fmc=([\'\"])(.*?)\2.*?>[\s\n\r]*<([a-zA-Z0-9]+).*?>(.*?)</\4>

完整的代码如下:

here

0
投票

正则表达式确实是错误的解决方案,但这可能有效:

import re

f = """<corpus>
    <ver id="18" etude="EC1_Elec" elec="oui" niveau="1" critere="1.3" type="discours">
        <part code="EC1_Elec_IW04_0">Ça existe sur des gros parcs Hlm mais c'est macro.</part>
    </ver>
    <ver id="30" etude="EC1_Elec" elec="oui" niveau="2" critere="" origine="IW" type="discours" fmc="motivation">
        <part code="EC1_Elec_IW01_0">Avant 75 on n'a pas isolé puis après, au fur et à mesure des règlementations.</part>
    </ver>
    <ver id="54" etude="EC1_Elec" elec="oui" niveau="1" critere="" origine="IW" type="discours" fmc="condition">
        <part code="EC1_Elec_IW10_0">Le deuxième boitier, il est où ? s'il y en a un qui est à l'intérieur et qui remplace un bout de l'isolation, il est caché OK.</part>
    </ver>
    <ver id="897" etude="EC3_Elec" elec="oui" niveau="4" critere="4.1" origine="TR" type="discours">
        <part code="EC3_Elec_TR2_1">Avec l'économie d'énergie, on va imposer de plus en plus d'automatismes,</part>
        <iwer>Çava influencer la demande pour ce type de solution c'est ça ?</iwer>
        <part code="EC3_Elec_TR2_1">Je pense oui</part>
    </ver>
</corpus>"""

regex = r'<([a-zA-Z0-9]+)[^\/]*?fmc=([\'\"])(.*?)\2.*?>[\s\n\r]*<([a-zA-Z0-9]+).*?>(.*?)</\4>'

matches = re.findall(regex, f)

for x in matches:
    print(x[2] + " " + x[4])

fmc="(.*?)".*?<part.*?>(.*?)</part>

您想要的结果将在https://regex101.com/r/M7LJLU/1\1中。


0
投票

这是更适合XML解析器的工作。我使用\2资源库中的untangle

PyPI

打印:

import untangle

xml = """<?xml version = "1.0" encoding="UTF-8" standalone="yes" ?>
<corpus>
    <ver id="18" etude="EC1_Elec" elec="oui" niveau="1" critere="1.3" type="discours">
        <part code="EC1_Elec_IW04_0">Ça existe sur des gros parcs Hlm mais c'est macro.</part>
    </ver>
    <ver id="30" etude="EC1_Elec" elec="oui" niveau="2" critere="" origine="IW" type="discours" fmc="motives">
        <part code="EC1_Elec_IW01_0">Avant 75 on n'a pas isolé puis après, au fur et à mesure des règlementations.</part>
    </ver>
    <ver id="54" etude="EC1_Elec" elec="oui" niveau="1" critere="" origine="IW" type="discours" fmc="condition">
        <part code="EC1_Elec_IW10_0">Le deuxième boitier, il est où ? s'il y en a un qui est à l'intérieur et qui remplace un bout de l'isolation, il est caché OK.</part>
    </ver>
    <ver id="897" etude="EC3_Elec" elec="oui" niveau="4" critere="4.1" origine="TR" type="discours" fmc="obstacle">
        <part code="EC3_Elec_TR2_1">Avec l'économie d'énergie, on va imposer de plus en plus d'automatismes,</part>
        <iwer>Çava influencer la demande pour ce type de solution c'est ça ?</iwer>
        <part code="EC3_Elec_TR2_1">Je pense oui</part>
    </ver>
</corpus>
"""

doc = untangle.parse(xml)
for ver in doc.corpus.ver:
    if ver['fmc'] is None: continue
    print(f"id={ver['id']}, fmc={ver['fmc']}")
    for part in ver.part:
        print(f"   part={part.cdata}")

0
投票

为什么不使用id=30, fmc=motives part=Avant 75 on n'a pas isolé puis après, au fur et à mesure des règlementations. id=54, fmc=condition part=Le deuxième boitier, il est où ? s'il y en a un qui est à l'intérieur et qui remplace un bout de l'isolation, il est caché OK. id=897, fmc=obstacle part=Avec l'économie d'énergie, on va imposer de plus en plus d'automatismes, part=Je pense oui 解析XML?恕我直言,让lxml解析xml并使用例如导航到结果元素树要容易得多。 XPath查找您想要的东西。

lxml
# install lxml
pip3 install lxml

然后这就是完成窍门的代码!

# xml snippet
xml = """\
<?xml version = "1.0" encoding="UTF-8" standalone="yes" ?>
<corpus>
    <ver id="18" etude="EC1_Elec" elec="oui" niveau="1" critere="1.3" type="discours">
        <part code="EC1_Elec_IW04_0">Ça existe sur des gros parcs Hlm mais c'est macro.</part>
    </ver>
    <ver id="30" etude="EC1_Elec" elec="oui" niveau="2" critere="" origine="IW" type="discours" fmc="motives">
        <part code="EC1_Elec_IW01_0">Avant 75 on n'a pas isolé puis après, au fur et à mesure des règlementations.</part>
    </ver>
    <ver id="54" etude="EC1_Elec" elec="oui" niveau="1" critere="" origine="IW" type="discours" fmc="condition">
        <part code="EC1_Elec_IW10_0">Le deuxième boitier, il est où ? s'il y en a un qui est à l'intérieur et qui remplace un bout de l'isolation, il est caché OK.</part>
    </ver>
    <ver id="897" etude="EC3_Elec" elec="oui" niveau="4" critere="4.1" origine="TR" type="discours" fmc="obstacle">
        <part code="EC3_Elec_TR2_1">Avec l'économie d'énergie, on va imposer de plus en plus d'automatismes,</part>
        <iwer>Çava influencer la demande pour ce type de solution c'est ça ?</iwer>
        <part code="EC3_Elec_TR2_1">Je pense oui</part>
    </ver>
</corpus>
"""

输出:

# use lxml...
from lxml import etree
# parse the xml snippet into an object tree
tree = etree.fromstring(bytes(xml, encoding='utf-8'))
# find all elements that have "fmc" attribute
for e in tree.findall(".//*[@fmc]"):
    label = e.xpath("./@fmc")[0]
    for c in e.findall("./part"):
        # print value of "fmc" attribute and text of all <part> elements
        print(f"{label:15}{c.text}")
© www.soinside.com 2019 - 2024. All rights reserved.