python这样的xml配置文件如何读取

Bill_Zhao610 2008-12-01 02:34:04
自己折腾了半天,没搞定.所以大家帮帮忙.
<?xml version="1.0" encoding="utf-8"?>
<Conf>
<DBconf>
<DB>
<Desc>abc</Desc>
<ConnStr>DB_192.168.3.1</ConnStr>
<UserName>system</UserName>
<PassWd>aa</PassWd>
</DB>
<DB>
<Desc>bb</Desc>
<ConnStr>ORA9i_192.168.3.1</ConnStr>
<UserName>system</UserName>
<PassWd>system</PassWd>
</DB>
<DB>
<Desc>ddd</Desc>
<ConnStr>ORA9i_192.168.3.1</ConnStr>
<UserName>system</UserName>
<PassWd>system</PassWd>
</DB>
</DBconf>
<Otherconf>
<a>aaa</a>
<c>aaa</c>
</Otherconf>
</Conf>
...全文
384 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
chuajiang 2011-06-23
  • 打赏
  • 举报
回复
顶,试过了,很好用,(*^__^*) 嘻嘻……
DDGG 2008-12-05
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 Bill_Zhao610 的回复:]
filter(lambda n: isinstance(n, minidom.Element), node.childNodes)
不是很明白 这个n是如何赋值,赋的什么值?
[/Quote]

对于 node.childNodes 中的每一项,以n作为参数调用lambda n这个临时函数,当该函数返回真的时候(即 isinstance(n, minidom.Element) == True ),添加到结果列表中,filter返回这个结果列表。
Bill_Zhao610 2008-12-02
  • 打赏
  • 举报
回复
filter(lambda n: isinstance(n, minidom.Element), node.childNodes)
不是很明白 这个n是如何赋值,赋的什么值?
Bill_Zhao610 2008-12-02
  • 打赏
  • 举报
回复
def get_childern(node):

return filter(lambda n: isinstance(n, minidom.Element), node.childNodes)

这句看不太懂噢,谁能解释一下

lixq2000 2008-12-02
  • 打赏
  • 举报
回复
学习!
killbug2004 2008-12-01
  • 打赏
  • 举报
回复
学习了,我还在学w3c关于xml的标准
DDGG 2008-12-01
  • 打赏
  • 举报
回复
忘了说,上面的程序是倾向于读取属性比较丰富的xml,类似于下面这样的:

<?xml version="1.0" encoding="utf-8"?>
<config desc="Line8Center" line="8">
<stations>
<ip base="192.168.8" />
<station name="市光路站" />
<station name="嫩江路站" />
<station name="翔殷路站" />
<station name="黄兴公园站" />
<station name="延吉中路站" />
<station name="黄兴路站" />
<station name="江浦路站" />
<station name="鞍山新村站" />
<station name="四平路站" />
<station name="曲阳路站" />
<station name="虹口足球场站" />
<station name="西藏北路站" />
<station name="中兴路站" />
<station name="曲阜路站" />
<station name="人民广场站" />
<station name="大世界站" />
<station name="老西门站" />
<station name="陆家浜路站" />
<station name="西藏南路站" />
<station name="周家渡路站" />
<station name="耀华路站" />
<station name="成山路站" />
<station name="杨思站" />
<station name="济阳路站" />
<station name="凌兆新村" />
<station name="芦恒路站" />
<station name="浦江镇站" />
<station name="江月路站" />
<station name="浦江世博家园" />
<station name="航天公园" />
<station name="车辆段" is_park="True" />
<station name="停车场" is_park="True" />
</stations>
<boxes>
<box name="防灾调" id="1" port="9" in="3" rec="8" />
<box name="总调" id="2" port="7" in="1" rec="6" />
<box name="列调" id="3" port="8" in="2" rec="7" />
</boxes>
<pis remote="192.168.8.223:1001" />
</config>


所以对于<node></node>之间的正文反而用_text来表示了,需要用dict_["node"]["_text"]的方式来访问。
对于<node attr1="123"></node>则可以直接通过dict_["node"]["attr1"]访问属性attr1。
DDGG 2008-12-01
  • 打赏
  • 举报
回复
同楼上的,推荐用elementtree这个模块(它已经被包含在ActivePython 2.5中),然后自己写一段小程序来把xml读取成字典结构:

dictxml.py
import elementtree.ElementTree as ET

def attr_gbk(elem, name):
return elem.attrib.get(name).encode("GBK")

def attr_int(elem, name):
return int(elem.attrib.get(name))

def attr_bool(elem, name):
return bool(elem.attrib.get(name))

def attr(elem, *args):
if len(args) > 1:
result = []
for name in args:
result.append(attr(elem, name))
return result

[name] = args
value = elem.attrib.get(name)
if not value:
return value
elif isinstance(value, unicode):
return value.encode("GBK")
elif value.isdigit():
return int(value)
elif value.lower() in ["true", "false"]:
return value.lower() == "true"
else:
return value

def fix_attribs(elem):
dict_ = {}
for key in elem.attrib:
dict_.update({key: attr(elem, key)})
return dict_

def build_dict(elem):
if elem is not None:
dict_ = {}
for subelem in elem:
if subelem.tag in dict_:
if not isinstance(dict_[subelem.tag], list):
dict_[subelem.tag] = [dict_[subelem.tag]]
dict_[subelem.tag].append(build_dict(subelem))
else:
dict_.update({subelem.tag: build_dict(subelem)})
if subelem.text and subelem.text.strip():
dict_.update({subelem.tag: {"_text": subelem.text}})
dict_.update(fix_attribs(elem))
return dict_
else:
return fix_attribs(elem)


sample.py
import dictxml

tree = dictxml.ET.parse("1.xml")
root = tree.getroot()
print dictxml.build_dict(root)


>>>
{'Otherconf': {'a': {'_text': 'aaa '}, 'c': {'_text': 'aaa '}}, 'DBconf': {'DB': [{'UserName': {'_text': 'system '}, 'PassWd': {'_text': 'aa '}, 'ConnStr': {'_text': 'DB_192.168.3.1 '}, 'Desc': {'_text': 'abc '}}, {'UserName': {'_text': 'system '}, 'PassWd': {'_text': 'system '}, 'ConnStr': {'_text': 'ORA9i_192.168.3.1 '}, 'Desc': {'_text': 'bb '}}, {'UserName': {'_text': 'system '}, 'PassWd': {'_text': 'system '}, 'ConnStr': {'_text': 'ORA9i_192.168.3.1 '}, 'Desc': {'_text': 'ddd '}}]}}
>>>
iambic 2008-12-01
  • 打赏
  • 举报
回复
方法挺多的,给个dom的例子吧:
xml = '''<?xml version="1.0" encoding="utf-8"?>
<Conf>
<DBconf>
<DB>
<Desc>abc </Desc>
<ConnStr>DB_192.168.3.1 </ConnStr>
<UserName>system </UserName>
<PassWd>aa </PassWd>
</DB>
<DB>
<Desc>bb </Desc>
<ConnStr>ORA9i_192.168.3.1 </ConnStr>
<UserName>system </UserName>
<PassWd>system </PassWd>
</DB>
<DB>
<Desc>ddd </Desc>
<ConnStr>ORA9i_192.168.3.1 </ConnStr>
<UserName>system </UserName>
<PassWd>system </PassWd>
</DB>
</DBconf>
<Otherconf>
<a>aaa </a>
<c>aaa </c>
</Otherconf>
</Conf>
'''

from xml.dom import minidom
def get_childern(node):
return filter(lambda n: isinstance(n, minidom.Element), node.childNodes)

doc = minidom.parseString(xml)
root = doc.childNodes[0]

DBconf, Otherconf = get_childern(root)

for DB in get_childern(DBconf):
for n in get_childern(DB):
print n.tagName, n.firstChild.data

print

for n in get_childern(Otherconf):
print n.tagName, n.firstChild.data


输出:
Desc abc
ConnStr DB_192.168.3.1
UserName system
PassWd aa
Desc bb
ConnStr ORA9i_192.168.3.1
UserName system
PassWd system
Desc ddd
ConnStr ORA9i_192.168.3.1
UserName system
PassWd system

a aaa
c aaa


网上还有些把xml转换成字典结构的,其实挺适合你的这个。

37,718

社区成员

发帖
与我相关
我的任务
社区描述
JavaScript,VBScript,AngleScript,ActionScript,Shell,Perl,Ruby,Lua,Tcl,Scala,MaxScript 等脚本语言交流。
社区管理员
  • 脚本语言(Perl/Python)社区
  • IT.BOB
加入社区
  • 近7日
  • 近30日
  • 至今

试试用AI创作助手写篇文章吧