使用XML minidom迭代图形的后续操作

时间:2009-10-02 16:00:12

标签: python parsing xmldom

这是问题(Link

的后续行动

我打算做的是使用XML来创建使用NetworkX的图形。查看下面的DOM结构,同一节点中的所有节点之间应该有一条边,并且参加过同一会议的所有节点都应该有一个节点到该会议。总而言之,所有在纸上合作的作者应该相互联系,所有参加过特定会议的作者都应该与该会议相关联。

<conference name="CONF 2009">
<paper>
<author>Yih-Chun Hu(UIUC)</author>
<author>David McGrew(Cisco Systems)</author>
<author>Adrian Perrig(CMU)</author>
<author>Brian Weis(Cisco Systems)</author>
<author>Dan Wendlandt(CMU)</author>
</paper>
<paper>
<author>Dan Wendlandt(CMU)</author>
<author>Ioannis Avramopoulos(Princeton)</author>
<author>David G. Andersen(CMU)</author>
<author>Jennifer Rexford(Princeton)</author>
</paper>
</conference>

我已经想出如何将作者与会议联系起来,但我不确定如何将作者彼此联系起来。我遇到困难的是如何迭代在同一张纸上工作并将它们连接在一起的作者。

    dom = parse(filepath)
    conference=dom.getElementsByTagName('conference')
    for node in conference:
        conf_name=node.getAttribute('name')
        print conf_name
        G.add_node(conf_name)

    #The nodeValue is split in order to get the name of the author 
#and to exclude the university they are part of

        plist=node.getElementsByTagName('paper')
        for p in plist:
            author=str(p.childNodes[0].nodeValue)
            author= author.split("(")
#Figure out a way to create edges between authors in the same <paper> </paper>

        alist=node.getElementsByTagName('author')
        for a in alist:
            authortext= str(a.childNodes[0].nodeValue).split("(")

            if authortext[0] in dict:
                edgeQuantity=dict[authortext[0]]
                edgeQuantity+=1
                dict[authortext[0]]=edgeQuantity
                G.add_edge(authortext[0],conf_name)

            #Otherwise, add it to the dictionary and create an edge to the conference.
            else:
                dict[authortext[0]]= 1
                G.add_node(authortext[0])
                G.add_edge(authortext[0],conf_name)
                i+=1

2 个答案:

答案 0 :(得分:0)

  

我不确定如何将作者彼此联系起来。

您需要生成(作者,otherauthor)对,以便将它们添加为边。这样做的典型方法是嵌套迭代:

for thing in things:
    for otherthing in things:
        add_edge(thing, otherthing)

这是一个天真的实现,包括自我循环(给作者一个连接自己的边缘),你可能想要也可能不想要;它还包括(1,2)和(2,1),如果你正在做一个无向图是多余的。 (在Python 2.6中,内置的permutations生成器也可以这样做。)这是一个修复这些东西的生成器:

def pairs(l):
    for i in range(len(l)-1):
        for j in range(i+1, len(l)):
            yield l[i], l[j]

我没有使用过NetworkX,但是看看doc似乎说你可以在同一个节点上调用add_node两次(第二次没有任何事情发生)。如果是这样,您可以丢弃您用来试图跟踪您插入的节点的字典。此外,似乎说如果您向未知节点添加边缘,它将自动为您添加该节点。所以应该可以使代码更短:

for conference in dom.getElementsByTagName('conference'):
    var conf_name= node.getAttribute('name')
    for paper in conference.getElementsByTagName('paper'):
        authors= paper.getElementsByTagName('author')
        auth_names= [author.firstChild.data.split('(')[0] for author in authors]

        # Note author's conference attendance
        #
        for auth_name in auth_names:
            G.add_edge(auth_name, conf_name)

        # Note combinations of authors working on same paper
        #
        for auth_name, other_name in pairs(auth_names):
            G.add_edge(auth_name, otherauth_name)

答案 1 :(得分:0)

我不完全确定你在寻找什么,但根据你的描述,我把一个图表汇总在一起,我认为它包含了你描述的关系。

http://imgur.com/o2HvT.png

我使用openfst来做到这一点。我发现在插入代码之前清楚地布局图形关系要容易得多。

另外,你真的需要在作者之间产生明确的边缘吗?这似乎是一个遍历问题。