6

次の reST 入力があるとします。

Some text ...

:foo: bar

Some text ...

私が最終的にやりたいのは、次のような口述です:

{"foo": "bar"}

私はこれを使用しようとしました:

tree = docutils.core.publish_parts(text)

フィールドリストを解析しますが、最終的に疑似 XML がtree["whole"]?次のようになります。

<document source="<string>">
    <docinfo>
        <field>
            <field_name>
                foo
            <field_body>
                <paragraph>
                    bar

treedict には他の有用な情報が含まれておらず、単なる文字列であるため、reST ドキュメントからフィールド リストを解析する方法がわかりません。どうすればいいですか?

4

3 に答える 3

7

次のコードのようなものを使用してみることができます。publish_parts私が使用したメソッドを使用するのではなくpublish_doctree、ドキュメントの疑似 XML 表現を取得します。次に、すべてのfield要素を抽出するために XML DOM に変換しました。次に、各要素の最初の要素field_nameと要素を取得します。field_bodyfield

from docutils.core import publish_doctree

source = """Some text ...

:foo: bar

Some text ...
"""

# Parse reStructuredText input, returning the Docutils doctree as
# an `xml.dom.minidom.Document` instance.
doctree = publish_doctree(source).asdom()

# Get all field lists in the document.
fields = doctree.getElementsByTagName('field')

d = {}

for field in fields:
    # I am assuming that `getElementsByTagName` only returns one element.
    field_name = field.getElementsByTagName('field_name')[0]
    field_body = field.getElementsByTagName('field_body')[0]

    d[field_name.firstChild.nodeValue] = \
        " ".join(c.firstChild.nodeValue for c in field_body.childNodes)

print d # Prints {u'foo': u'bar'}

xml.domモジュールは最も簡単に操作できるものではありません (なぜ、単なる例.firstChild.nodeValueではなく使用する必要があるのでしょうか)。 . lxml を使用する場合は、XPATH 表記を使用してすべての,および要素を検索することもできます。.nodeValuefieldfield_namefield_body

于 2012-05-28T09:27:25.623 に答える
0

負担は少ないが、もろいかもしれない別の解決策があります。ノード クラスhttps://sourceforge.net/p/docutils/code/HEAD/tree/trunk/docutils/docutils/nodes.pyの実装を確認すると、プルに使用できる walk メソッドがサポートされていることがわかります。データの 2 つの異なる xml 表現を作成する必要なく、必要なデータを取り出します。これが、プロトタイプコードで現在使用しているものです。

https://github.com/h4ck3rm1k3/gcc-introspector/blob/master/peewee_adaptor.py#L33

from docutils.core import publish_doctree
import docutils.nodes

その後

def walk_docstring(prop):
    doc = prop.__doc__
    doctree = publish_doctree(doc)
    class Walker:
        def __init__(self, doc):
            self.document = doc
            self.fields = {}
        def dispatch_visit(self,x):
            if isinstance(x, docutils.nodes.field):
                field_name = x.children[0].rawsource
                field_value = x.children[1].rawsource
                self.fields[field_name]=field_value
    w = Walker(doctree)
    doctree.walk(w)
    # the collected fields I wanted
    pprint.pprint(w.fields)
于 2015-02-08T16:48:08.707 に答える