-
Notifications
You must be signed in to change notification settings - Fork 51
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Continue parsing after an using ijson.items on an array #54
Comments
@dzamo what you are asking is basically not possible with the code you came up with. When the ijson generators raise a I think your confusion comes from a wrong (but common) expectation as well: you probably think $> echo '{"arr": [1, 2, 3], "arr": [1, 2, 3]}' | python -m ijson.dump -m items -p arr.item
#: value
--------
0: 1
1: 2
2: 3
3: 1
4: 2
5: 3
There are more reasons, but those are enough I think to explain the situation. To implement what you need you'll have to do all your parsing with the results from |
@rtobar: thank you for the pointer, your suggestion works nicely. I've now got a generator called def _items_once(event_stream, prefix):
'''
Generator dispatching native Python objects constructed from the ijson
events under the next occurrence of the given prefix. It is very
similar to ijson.items except that it will not consume the entire JSON
stream looking for occurrences of prefix, but rather stop after
completing the next encountered occurrence of prefix.
'''
current = None
while current != prefix:
current, event, value = next(event_stream)
while current == prefix:
if event in ('start_map', 'start_array'):
object_depth = 1
builder = ObjectBuilder() # imported from ijson.common
while object_depth:
builder.event(event, value)
current, event, value = next(event_stream)
if event in ('start_map', 'start_array'):
object_depth += 1
elif event in ('end_map', 'end_array'):
object_depth -= 1
del builder.containers[:]
yield builder.value
else:
yield value
current, event, value = next(event_stream) |
Thanks @dzamo for putting the code up, I'm sure somebody else will find it useful too. I'm reluctant to add something like this to ijson. Not because it's a bad idea on itself, but because it's a bit of a niche use case, and adding it (and maintaining it in the longer term) is a bit more than copy-pasting your code. In particular, the If more and more people are finding this to be useful we could re-evaluate; otherwise having the code available here is good enough I think. Thanks again! |
Description
I want to parse an array using
ijson.items
, stop onStopIteration
, and then proceed to parse trailing content using the underlyingijson.parse
object. In the code below, the final line fails. If I replacewhile True
withfor i in range(3)
then I parse all ofarr
without aStopIteration
and I can go on to parse the trailing content. This doesn't help me though, because I don't know how longarr
is...Thank you for you help.
The text was updated successfully, but these errors were encountered: