1

考虑这个 XML 结构,一个 DDEX 标准的简化版本:

<doc>
<master>
 <ResourceInfo>
  <Name>Foo</Name>
  <Seq>1</Seq>
 </ResourceInfo>
 <ResourceInfo>
  <Name>Bar</Name>
  <Seq>2</Seq>
 </ResourceInfo>
</master>
<track>
 <Resource>
  <Name>Foo</Name>
 </Resource>
</track>
<track>
 <Resource>
  <Name>Bar</Name>
 </Resource>
</track>
</doc>

我想选择 ResourceInfo 节点,<master>其中的子节点与<Name>每个轨道节点的名称的文本值匹配,以获取 Seq 编号。

我可以通过获取每个轨道的 lxml 树并明确请求<ResourceInfo>' 来直接这样做:

track.xpath('/doc/master/ResourceInfo/Seq[../Name[text()="Foo"]]')

但这假设我知道每首曲目的名称并且可以提前明确说明。我希望能够对此进行愚蠢的映射,并以某种方式将 xpath 中的“Foo”替换为text()对当前曲目资源名称的一些引用。

text()这有点像在 master 中的 Name上加入轨道和资源,并text()在每个轨道中加入 Name。有没有一种简单的方法可以用 XPath 做到这一点?

我正在尝试遍历每个轨道,并从轨道中拉出 Seq。因此,我不能明确要求“Foo”。我需要反省 - “给我 Seq,它是 master 中节点的兄弟节点,其值与“中的当前节点<Name>匹配。<Name><track>

4

2 回答 2

2

我不确定我是否完全理解,但如果当前上下文是:

/doc/track/Resource/Name

并且您使用以下 XPath:

/doc/master/ResourceInfo[Name = current()]/Seq

你应该得到相同Seq的。ResourceInfoName

于 2013-02-16T03:24:30.210 回答
1

阅读您的评论后,我现在了解您的目标。Uou 可以简单地使用 Python 进行连接:

from lxml import etree

doc = etree.parse('sample.xml')

# gather resources
resources = {}
for element in doc.xpath('/doc/master/ResourceInfo'):
    name = element[0].text
    seq  = element[1].text
    resources[name] = seq

# gather tracks
tracks = []
for element in doc.xpath('/doc/track/Resource/Name'):
    name = element.text
    tracks.append(name)

# join:

for track in tracks:
    print 'Track: %s, seq: %s' % (track, resources.get(track))

# returns: 
# Track: Foo, seq: 1
# Track: Bar, seq: 2

上一个答案:

XML 格式不正确:

<doc>
  <master>
    <ResourceInfo>
      <Name>Foo</Name>
      <Seq>1</Seq>
    </ResourceInfo>
    <ResourceInfo>
      <Name>Bar</Name>
      <Seq>2</Seq>
    </ResourceInfo>
  </master>
  <track>
    <Resource>
      <Name>Foo</Name>
    </Resource>
  </track>  <!-- was missing backslash -->
  <track>
    <Resource>
      <Name>Bar</Name>
    </Resource>
  </track>
</doc>

您的代码有效:

from lxml import etree

doc = etree.parse('a.xml')

for element in doc.xpath('/doc/master/ResourceInfo/Seq[../Name[text()="Foo"]]'):
    #print etree.tostring(element)
    print element.text  

# returns
# 1
于 2013-02-16T00:21:55.253 回答