xmltodict
xmltodict copied to clipboard
attributes not appearing in parse output even with xml_attribs = True
Thanks for a great tool!
I am having a problem with it though. I'm probably doing something wrong but it's not clear to me what. I have an xml document looking something like this
<api>
<cons id="79550" modified_dt="1526652449">
<firstname>Mackenzie</firstname>
...
</cons>
<cons id="79551" modified_dt="1526652549">
<firstname>Joe</firstname>
...
</cons>
<api>
I parse it with this:
xmltodict.parse(apiResult.body, item_depth=2, item_callback=handler, xml_attribs=True)
where apiResult.body
contains the xml shown above. But, in spite of the xml_attribs=True
, I see no @id
or @modified_dt
in the output after parsing in the handler, although all the elements in the original do appear.
The handler is coded as follows:
def handler(_, cons):
print (cons)
mc = MatchChecker(cons)
mc.check()
return True
What might I be doing wrong?
I don't think I'm doing anything wrong. I think that what is happening is that xml_attribs in my parse call is being overlooked, and that all depths below the requested depth, get xml_attribs true by default. If I specify depth=1, then my depth 2 elements have the attributes show up. Previously, before turning xml_attribs true in my code, all depth 3 elements and below had attributes without my asking for them. So I can sort of make it work by using depth=1, and then have my handler iterate through the list of depth 2 (cons) elements. I don't think that's the way it's supposed to work. The handler should only be handling one element of the desired depth.
I am having the same problem... it's something not easily resolved with huge XML files that need iterating over a specific level.
<api>
<cons id="79550" modified_dt="1526652449">
<firstname>Mackenzie</firstname>
</cons>
<cons id="79551" modified_dt="1526652549">
<firstname>Joe</firstname>
</cons>
</api>
may be conveeted to
{
"api": {
"cons": [
{
"-id": "79550",
"-modified_dt": "1526652449",
"firstname": "Mackenzie"
},
{
"-id": "79551",
"-modified_dt": "1526652549",
"firstname": "Joe"
}
]
},
"#omit-xml-declaration": "yes"
}
fyi, I found that I can access the attribute using the path
argument in the item_callback
function. Try sth like:
def handler(path, cons):
print(path[1][1]['id'])
@stevecoh1 A workaround as @billcrook suggestion
def handler(path, cons):
if path and path[-1]:
cons.update({'@' + k: v for k, v in path[-1][-1].items()})
print (cons)
mc = MatchChecker(cons)
mc.check()
return True