Adding external information to ParseResults before return

和自甴很熟 提交于 2020-01-22 03:03:26

问题


I want to add external information to ParseResults before return. I return the results of parsing as asXML(). The external data represented as dictionary so as to parsed as XML in the final parsing.

This the code before adding external data from pyparsing import *

# a hypothetical outer parser, with an unparsed SkipTo element
color = oneOf("red orange yellow green blue purple")
expression = SkipTo("XXX") + Literal("XXX").setResultsName('ex') + color.setResultsName('color')

data = "JUNK 100 200 10 XXX green"
print expression.parseString(data).dump()

# main grammar
def minorgrammar(toks):
    # a simple inner grammar
    integer = Word(nums)
    grammar2 = integer("A").setResultsName('A') + integer("B").setResultsName('B') + integer("C").setResultsName('C')

    # use scanString to find the inner grammar
    # (since we just want the first occurrence, we can use next
    # instead of a for loop with a break)
    t,s,e = next(grammar2.scanString(toks[0],maxMatches=1))



    # remove 0'th element from toks
    del toks[0]

    # return a new ParseResults, the sum of t and everything 
    # in toks after toks[0] was removed
    return t + toks

grammar1 = expression.setParseAction(minorgrammar)
x = grammar1.parseString(data).asXML("main")
print x 

the output is

<main>
  <A>100</A>
  <B>200</B>
  <C>10</C>
  <ex>XXX</ex>
  <color>green</color>
</main>

the code after adding external data

    ...
    external_data = {'name':'omar', 'age':'40'}

    return t + toks + ParseResults(external_data)

grammar1 = expression.setParseAction(minorgrammar)

x = grammar1.parseString(data).asXML("main")

print x

the output

<main>
  <A>100</A>
  <B>200</B>
  <C>10</C>
  <ex>XXX</ex>
  <color>green</color>
  <ITEM>{&apos;age&apos;: &apos;40&apos;, &apos;name&apos;: &apos;omar&apos;}</ITEM>
</main>

I want the output in the form

<main>
  <A>100</A>
  <B>200</B>
  <C>10</C>
  <ex>XXX</ex>
  <color>green</color>
  <name>omar</name>
  <age>40</age>
</main>

What is the error in that code ? Thans


回答1:


One problem is this fragment:

external_data = {'name':'omar', 'age':'40'}
return t + toks + ParseResults(external_data)

ParseResults will take a dict as a constructor argument, but I don't think it will do what you want - it just assigns the dict as it's 0'th element, and does not assign any results names.

You can assign named values into a ParseResults by using its dict-style assignment:

pr = ParseResults(['omar','40'])
for k,v in external_data.items():
    pr[k] = v

See if this gets you closer to your desired format.

EDIT: Hmm, it seems asXML is more fussy about how named results get added to the ParseResults, than just setting the name. This will work better:

def addNamedResult(pr, value, name):
    addpr = ParseResults([value])
    addpr[name] = value
    pr += addpr

And then in your parse action, add the values with their names using:

addNamedResult(toks, 'omar', 'name')
addNamedResult(toks, '40', 'age')



回答2:


Thanks very much Paul. I modified your function to add a dictionary of data

...
external_data = {'name':'omar', 'age':'40'}
return t + toks +  addDicResult(external_data)
...

def addDicResult(dict):
     pr = ParseResults([])
     for k, v in dict.items():
         addpr = ParseResults([v])
         addpr[k] = v
         pr += addpr
     return pr

The output
<main>
  <A>100</A>
  <B>200</B>
  <C>10</C>
  <ex>XXX</ex>
  <color>green</color>
  <age>40</age>
  <name>omar</name>
</main>


来源:https://stackoverflow.com/questions/11696338/adding-external-information-to-parseresults-before-return

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!