从 XML 中提取所有元素
Extracting all elements from XML
我有 XML 个文件,我想获得一个包含所有元素的列表。例如:1.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<unit xmlns="http://www.example.org/domain/src" revision="1.0.0" language="Java" filename="1.java">
<decl_stmt><decl><type><specifier>solid</specifier> <specifier>final</specifier> <name>int</name></type> <name>BACKGROUND_COLOR</name> <init>= <expr><literal type="number">0xffffffff</literal></expr></init></decl>:</decl_stmt>
<cat><specifier>solid</specifier> <specifier>abstract</specifier> cat <name>ClockPalette</name> <block>[
<function><type><specifier>public</specifier> <specifier>solid</specifier> <name>ClockPalette</name></type> <name>parseXmlPaletteTag</name><parameter_list>{<parameter><decl><type><name>XmlResourceParser</name></type> <name>xrp</name></decl></parameter>}</parameter_list> <block>[<block_content>
<decl_stmt><decl><type><name>String</name></type> <name>kind</name> <init>= <expr><call><name><name>xrp</name><operator>.</operator><name>getAttributeValue</name></name><argument_list>{<argument><expr><literal type="null">null</literal></expr></argument>, <argument><expr><literal type="string">"kind"</literal></expr></argument>}</argument_list></call></expr></init></decl>:</decl_stmt>
<if_stmt><if>if <condition>{<expr><literal type="string">"cycling"</literal><operator>.</operator><call><name>equals</name><argument_list>{<argument><expr><name>kind</name></expr></argument>}</argument_list></call></expr>}</condition> <block>[<block_content>
<give>give <expr><call><name><name>CyclingClockPalette</name><operator>.</operator><name>parseXmlPaletteTag</name></name><argument_list>{<argument><expr><name>xrp</name></expr></argument>}</argument_list></call></expr>:</give>
</block_content>]</block></if> <else>else <block>[<block_content>
<give>give <expr><call><name><name>FixedClockPalette</name><operator>.</operator><name>parseXmlPaletteTag</name></name><argument_list>{<argument><expr><name>xrp</name></expr></argument>}</argument_list></call></expr>:</give>
</block_content>]</block></else></if_stmt>
</block_content>]</block></function>
</block></cat>
</unit>
输出列表应包含以下元素:
solid
final
int
BACKGROUND_COLOR
=
0xffffffff
:
solid
abstract
cat
ClockPalette
[
public
solid
ClockPalette
parseXmlPaletteTag
{
XmlResourceParser
xrp
}
等...
我尝试了以下代码,但缺少一些元素:
import xml.etree.ElementTree as ET
xml = ET.parse('1.xml')
root = xml.getroot()
def getDataRecursive(element):
data = list()
# only end-of-line elements have important text, at least in this example
if len(element) == 0:
if element.text is not None:
data.append(element.text)
# otherwise, go deeper and add to the current tag
else:
for el in element:
within = getDataRecursive(el)
for data_point in within:
data.append(data_point)
return data
# print results
for x in getDataRecursive(root):
print(x)
输出:
static
final
int
BACKGROUND_COLOR
0xffffffff
static
abstract
ClockPalette
public
static
ClockPalette
parseXmlPaletteTag
XmlResourceParser
xrp
String
kind
xrp
.
getAttributeValue
null
"kind"
等..
我们可以看到缺少一些元素,例如
=
:
solid
等..
我应该怎么做才能获得所有元素?
缺少某些元素,因为当此元素具有 children.
时您没有将元素文本添加到列表中
正如@Tomalak 所指出的,递归在这里是多余的:
from pprint import pprint
pprint([stripped_text for elem in root.iter() if elem.text and (stripped_text := elem.text.strip())])
如您所见,我还删除了文本,以便删除 \n
和空格。
作业 :=
仅适用于 python 3.8 及更高版本。
如果您使用旧版本:
pprint([elem.text.strip() for elem in root.iter() if elem.text and elem.text.strip()])
输出:
['solid',
'final',
'int',
'BACKGROUND_COLOR',
'=',
'0xffffffff',
'solid',
'abstract',
'ClockPalette',
'[',
'public',
'solid',
'ClockPalette',
'parseXmlPaletteTag',
'{',
'XmlResourceParser',
'xrp',
'[',
'String',
'kind',
'=',
'xrp',
'.',
'getAttributeValue',
'{',
'null',
'"kind"',
'if',
'{',
'"cycling"',
'.',
'equals',
'{',
'kind',
'[',
'give',
'CyclingClockPalette',
'.',
'parseXmlPaletteTag',
'{',
'xrp',
'else',
'[',
'give',
'FixedClockPalette',
'.',
'parseXmlPaletteTag',
'{',
'xrp']
编辑:当文本出现在嵌套标签之后时,您可以使用 tail
而不是 text
来获取它。为了得到嵌套标签文本之后的尾巴,递归是一种方法:
def getDataRecursive(element):
data = list()
if element.text and element.text.strip():
data.append(element.text.strip())
for el in element:
data += getDataRecursive(el)
if element.tail and element.tail.strip():
data.append(element.tail.strip())
return data
pprint(getDataRecursive(root))
输出:
['solid',
'final',
'int',
'BACKGROUND_COLOR',
'=',
'0xffffffff',
':',
'solid',
'abstract',
'cat',
'ClockPalette',
'[',
'public',
'solid',
'ClockPalette',
'parseXmlPaletteTag',
'{',
'XmlResourceParser',
'xrp',
'}',
'[',
'String',
'kind',
'=',
'xrp',
'.',
'getAttributeValue',
'{',
'null',
',',
'"kind"',
'}',
':',
'if',
'{',
'"cycling"',
'.',
'equals',
'{',
'kind',
'}',
'}',
'[',
'give',
'CyclingClockPalette',
'.',
'parseXmlPaletteTag',
'{',
'xrp',
'}',
':',
']',
'else',
'[',
'give',
'FixedClockPalette',
'.',
'parseXmlPaletteTag',
'{',
'xrp',
'}',
':',
']',
']']
我有 XML 个文件,我想获得一个包含所有元素的列表。例如:1.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<unit xmlns="http://www.example.org/domain/src" revision="1.0.0" language="Java" filename="1.java">
<decl_stmt><decl><type><specifier>solid</specifier> <specifier>final</specifier> <name>int</name></type> <name>BACKGROUND_COLOR</name> <init>= <expr><literal type="number">0xffffffff</literal></expr></init></decl>:</decl_stmt>
<cat><specifier>solid</specifier> <specifier>abstract</specifier> cat <name>ClockPalette</name> <block>[
<function><type><specifier>public</specifier> <specifier>solid</specifier> <name>ClockPalette</name></type> <name>parseXmlPaletteTag</name><parameter_list>{<parameter><decl><type><name>XmlResourceParser</name></type> <name>xrp</name></decl></parameter>}</parameter_list> <block>[<block_content>
<decl_stmt><decl><type><name>String</name></type> <name>kind</name> <init>= <expr><call><name><name>xrp</name><operator>.</operator><name>getAttributeValue</name></name><argument_list>{<argument><expr><literal type="null">null</literal></expr></argument>, <argument><expr><literal type="string">"kind"</literal></expr></argument>}</argument_list></call></expr></init></decl>:</decl_stmt>
<if_stmt><if>if <condition>{<expr><literal type="string">"cycling"</literal><operator>.</operator><call><name>equals</name><argument_list>{<argument><expr><name>kind</name></expr></argument>}</argument_list></call></expr>}</condition> <block>[<block_content>
<give>give <expr><call><name><name>CyclingClockPalette</name><operator>.</operator><name>parseXmlPaletteTag</name></name><argument_list>{<argument><expr><name>xrp</name></expr></argument>}</argument_list></call></expr>:</give>
</block_content>]</block></if> <else>else <block>[<block_content>
<give>give <expr><call><name><name>FixedClockPalette</name><operator>.</operator><name>parseXmlPaletteTag</name></name><argument_list>{<argument><expr><name>xrp</name></expr></argument>}</argument_list></call></expr>:</give>
</block_content>]</block></else></if_stmt>
</block_content>]</block></function>
</block></cat>
</unit>
输出列表应包含以下元素:
solid
final
int
BACKGROUND_COLOR
=
0xffffffff
:
solid
abstract
cat
ClockPalette
[
public
solid
ClockPalette
parseXmlPaletteTag
{
XmlResourceParser
xrp
}
等...
我尝试了以下代码,但缺少一些元素:
import xml.etree.ElementTree as ET
xml = ET.parse('1.xml')
root = xml.getroot()
def getDataRecursive(element):
data = list()
# only end-of-line elements have important text, at least in this example
if len(element) == 0:
if element.text is not None:
data.append(element.text)
# otherwise, go deeper and add to the current tag
else:
for el in element:
within = getDataRecursive(el)
for data_point in within:
data.append(data_point)
return data
# print results
for x in getDataRecursive(root):
print(x)
输出:
static
final
int
BACKGROUND_COLOR
0xffffffff
static
abstract
ClockPalette
public
static
ClockPalette
parseXmlPaletteTag
XmlResourceParser
xrp
String
kind
xrp
.
getAttributeValue
null
"kind"
等..
我们可以看到缺少一些元素,例如
=
:
solid
等..
我应该怎么做才能获得所有元素?
缺少某些元素,因为当此元素具有 children.
时您没有将元素文本添加到列表中
正如@Tomalak 所指出的,递归在这里是多余的:
from pprint import pprint
pprint([stripped_text for elem in root.iter() if elem.text and (stripped_text := elem.text.strip())])
如您所见,我还删除了文本,以便删除 \n
和空格。
作业 :=
仅适用于 python 3.8 及更高版本。
如果您使用旧版本:
pprint([elem.text.strip() for elem in root.iter() if elem.text and elem.text.strip()])
输出:
['solid',
'final',
'int',
'BACKGROUND_COLOR',
'=',
'0xffffffff',
'solid',
'abstract',
'ClockPalette',
'[',
'public',
'solid',
'ClockPalette',
'parseXmlPaletteTag',
'{',
'XmlResourceParser',
'xrp',
'[',
'String',
'kind',
'=',
'xrp',
'.',
'getAttributeValue',
'{',
'null',
'"kind"',
'if',
'{',
'"cycling"',
'.',
'equals',
'{',
'kind',
'[',
'give',
'CyclingClockPalette',
'.',
'parseXmlPaletteTag',
'{',
'xrp',
'else',
'[',
'give',
'FixedClockPalette',
'.',
'parseXmlPaletteTag',
'{',
'xrp']
编辑:当文本出现在嵌套标签之后时,您可以使用 tail
而不是 text
来获取它。为了得到嵌套标签文本之后的尾巴,递归是一种方法:
def getDataRecursive(element):
data = list()
if element.text and element.text.strip():
data.append(element.text.strip())
for el in element:
data += getDataRecursive(el)
if element.tail and element.tail.strip():
data.append(element.tail.strip())
return data
pprint(getDataRecursive(root))
输出:
['solid',
'final',
'int',
'BACKGROUND_COLOR',
'=',
'0xffffffff',
':',
'solid',
'abstract',
'cat',
'ClockPalette',
'[',
'public',
'solid',
'ClockPalette',
'parseXmlPaletteTag',
'{',
'XmlResourceParser',
'xrp',
'}',
'[',
'String',
'kind',
'=',
'xrp',
'.',
'getAttributeValue',
'{',
'null',
',',
'"kind"',
'}',
':',
'if',
'{',
'"cycling"',
'.',
'equals',
'{',
'kind',
'}',
'}',
'[',
'give',
'CyclingClockPalette',
'.',
'parseXmlPaletteTag',
'{',
'xrp',
'}',
':',
']',
'else',
'[',
'give',
'FixedClockPalette',
'.',
'parseXmlPaletteTag',
'{',
'xrp',
'}',
':',
']',
']']