xml的python xpath解析<;lb/>;

xml的python xpath解析<;lb/>;,python,xml,xpath,lxml,Python,Xml,Xpath,Lxml,我正在使用xpath解析xml文件 从lxml导入etree 示例=“” 1.汽车是 -大、黄色和红色 -有一个大马达 -并且还具有 大座位。 ''' 我想按以下方式序列化上述XML文件: {"_3a327f0003": "1. A car is", "_3a327f0004":"- big, yellow and red;" "_3a327f0005":"- has a b

我正在使用xpath解析xml文件

从lxml导入etree
示例=“”

1.汽车是

-大、黄色和红色

-有一个大马达

-并且还具有 大座位。

'''
我想按以下方式序列化上述XML文件:

{"_3a327f0003": "1. A car is",
 "_3a327f0004":"- big, yellow and red;"
 "_3a327f0005":"- has a big motor;"
"_3a327f0006":"- and also has big seats"
基本上提取文本并构建一个字典,其中每个文本都属于他的
xml:id
。我的代码如下:

parser=etree.XMLParser(resolve\u entities=False,strip\u cdata=False,recover=True,ns\u clean=True)
XML_tree=etree.fromstring(例如.encode(),parser=parser)
all_paras=XML_tree.xpath('.//p[@XML:id]'))
段落列表=[]
对于所有段落中的段落:
mydict={}
mydict['text']=段落文本
对于attrib段中的att:
mykey=att
如果mykey中的“id”:
mykey='xmlid'
mydict[mykey]=段落属性[att]
段落列表。追加(mydict)
PDM_XML_序列化程序(示例)
它可以工作,但如果我有如下节点:

-并且还具有 大座位。

它不会从中提取零件

我应该如何修改:

XML_tree.xpath('.//p[@XML:id]'))
要获取

中的所有文本

编辑: 可以使用para.itertext(),但第一个节点也将返回其他节点的所有文本。

您可以使用lxml获取
p
元素的文本内容:

mydict['text'] = ''.join(para.itertext())
有关更通用的解决方案,请参见。

您可以使用lxml获取
p
元素的文本内容:

mydict['text'] = ''.join(para.itertext())

有关更通用的解决方案,请参见。

使用
xml.etree.ElementTree

import xml.etree.ElementTree as ET

xml = '''<div n="0001" type="car" xml:id="_3a327f0002">
                <p xml:id="_3a327f0003">
                1. A car is
                    <p xml:id="_3a327f0004"> - big, yellow and red;</p>
                    <p xml:id="_3a327f0005"> - has a big motor;</p>
                    <p xml:id="_3a327f0006"> - and also has <lb/>
                      big seats.
                    </p>
                </p>
                </div>'''


def _get_element_txt(element):
    txt = element.text
    children = list(element)
    if children:
        txt += children[0].tail.strip()
    return txt


root = ET.fromstring(xml)
data = {p.attrib['{http://www.w3.org/XML/1998/namespace}id']: _get_element_txt(p)
        for p in root.findall('.//p/p')}
for k, v in data.items():
    print(f'{k} --> {v}')

使用
xml.etree.ElementTree

import xml.etree.ElementTree as ET

xml = '''<div n="0001" type="car" xml:id="_3a327f0002">
                <p xml:id="_3a327f0003">
                1. A car is
                    <p xml:id="_3a327f0004"> - big, yellow and red;</p>
                    <p xml:id="_3a327f0005"> - has a big motor;</p>
                    <p xml:id="_3a327f0006"> - and also has <lb/>
                      big seats.
                    </p>
                </p>
                </div>'''


def _get_element_txt(element):
    txt = element.text
    children = list(element)
    if children:
        txt += children[0].tail.strip()
    return txt


root = ET.fromstring(xml)
data = {p.attrib['{http://www.w3.org/XML/1998/namespace}id']: _get_element_txt(p)
        for p in root.findall('.//p/p')}
for k, v in data.items():
    print(f'{k} --> {v}')

使用
lxml.etree
解析列表/听写理解中
所有段落中的所有元素。由于您的XML使用特殊的
XML
前缀,并且
lxml
还不支持解析属性中的命名空间前缀(请参见@mzjn的答案),因此下面使用
next
+
iter
来检索属性值

此外,要检索节点之间的所有文本值,
xpath(“text()”)
str.strip
.join
一起使用,以清除空格和换行符,并将它们连接在一起

from lxml import etree

example='''<div n="0001" type="car" xml:id="_3a327f0002">
                <p xml:id="_3a327f0003">
                1. A car is
                    <p xml:id="_3a327f0004"> - big, yellow and red;</p>
                    <p xml:id="_3a327f0005"> - has a big motor;</p>
                    <p xml:id="_3a327f0006"> - and also has <lb/>
                      big seats.
                    </p>
                </p>
                </div>'''
                
XML_tree = etree.fromstring(example)
all_paras = XML_tree.xpath('.//p[@xml:id]')

output = {
    next(iter(t.attrib.values())):" ".join(i.strip() 
        for i in t.xpath("text()")).strip()
    for t in all_paras
}

output
# {
#  '_3a327f0003': '1. A car is', 
#  '_3a327f0004': '- big, yellow and red;',
#  '_3a327f0005': '- has a big motor;',
#  '_3a327f0006': '- and also has big seats.'
# }
从lxml导入etree
示例=“”

1.汽车是

-大、黄色和红色

-有一个大马达

-并且还具有 大座位。

''' XML_tree=etree.fromstring(示例) all_paras=XML_tree.xpath('.//p[@XML:id]')) 输出={ 下一步(iter(t.attrib.values()):“”.join(i.strip()) 对于t.xpath中的i(“text()”).strip() 对于t,在所有段落中 } 输出 # { #“\u 3a327f0003”:“1.汽车是”, #“_3a327f0004”:”-大的,黄色和红色;”, #“_3a327f0005”:”-有一个大马达;”, #“_3a327f0006”:”-还有大座位。” # }
使用
lxml.etree
在列表/目录中解析
所有段落中的所有元素。由于您的XML使用特殊的
XML
前缀,并且
lxml
还不支持解析属性中的命名空间前缀(请参见@mzjn的答案),因此下面使用
next
+
iter
来检索属性值

此外,要检索节点之间的所有文本值,
xpath(“text()”)
str.strip
.join
一起使用,以清除空格和换行符,并将它们连接在一起

from lxml import etree

example='''<div n="0001" type="car" xml:id="_3a327f0002">
                <p xml:id="_3a327f0003">
                1. A car is
                    <p xml:id="_3a327f0004"> - big, yellow and red;</p>
                    <p xml:id="_3a327f0005"> - has a big motor;</p>
                    <p xml:id="_3a327f0006"> - and also has <lb/>
                      big seats.
                    </p>
                </p>
                </div>'''
                
XML_tree = etree.fromstring(example)
all_paras = XML_tree.xpath('.//p[@xml:id]')

output = {
    next(iter(t.attrib.values())):" ".join(i.strip() 
        for i in t.xpath("text()")).strip()
    for t in all_paras
}

output
# {
#  '_3a327f0003': '1. A car is', 
#  '_3a327f0004': '- big, yellow and red;',
#  '_3a327f0005': '- has a big motor;',
#  '_3a327f0006': '- and also has big seats.'
# }
从lxml导入etree
示例=“”

1.汽车是

-大、黄色和红色

-有一个大马达

-并且还具有 大座位。

''' XML_tree=etree.fromstring(示例) all_paras=XML_tree.xpath('.//p[@XML:id]')) 输出={ 下一步(iter(t.attrib.values()):“”.join(i.strip()) 对于t.xpath中的i(“text()”).strip() 对于t,在所有段落中 } 输出 # { #“\u 3a327f0003”:“1.汽车是”, #“_3a327f0004”:”-大的,黄色和红色;”, #“_3a327f0005”:”-有一个大马达;”, #“_3a327f0006”:”-还有大座位。” # }
根据您的示例,修改xpath以排除“A car is”文本。它还使用xpath函数
string
normalize space
para
节点作为字符串进行求值,并连接其文本节点,以及清理文本以匹配示例

from lxml import etree

example='''<div n="0001" type="car" xml:id="_3a327f0002">
                <p xml:id="_3a327f0003">
                1. A car is
                    <p xml:id="_3a327f0004"> - big, yellow and red;</p>
                    <p xml:id="_3a327f0005"> - has a big motor;</p>
                    <p xml:id="_3a327f0006"> - and also has <lb/>
                      big seats.
                    </p>
                </p>
                </div>'''

parser = etree.XMLParser(resolve_entities=False, strip_cdata=False, recover=True, ns_clean=True)

XML_tree = etree.fromstring(example.encode() , parser=parser)
all_paras = XML_tree.xpath('./p/p[@xml:id]')

list_of_paragraphs = []
for para in all_paras:
    mydict = {}
    mydict['text'] = para.xpath('normalize-space(string(.))')
    for att in para.attrib:
        mykey=att
        if 'id' in mykey:
            mykey='xmlid'
        mydict[mykey] = para.attrib[att]
    list_of_paragraphs.append(mydict)

PDM_XML_serializer(example)
从lxml导入etree
示例=“”

1.汽车是

-大、黄色和红色

-有一个大马达

-并且还具有 大座位。

''' parser=etree.XMLParser(resolve\u entities=False,strip\u cdata=False,recover=True,ns\u clean=True) XML_tree=etree.fromstring(例如.encode(),parser=parser) all_paras=XML_tree.xpath('./p/p[@XML:id]')) 段落列表=[] 对于所有段落中的段落: mydict={} mydict['text']=para.xpath('normalize-space(string(.))')) 对于attrib段中的att: mykey=att 如果mykey中的“id”: myk