如何在XPath中选择包含特定子元素的元素?

时间:2018-01-05 15:44:07

标签: xml xpath xpath-2.0

我有一些关于书籍的MARC21-XML文档。我想提取这本书翻译的名字。

以下是一本书的一个MARC21-XML文档的片段:

<?xml version="1.0" encoding="UTF-8"?>
  <record xmlns="http://www.loc.gov/MARC21/slim" type="Bibliographic">
    <datafield tag="700" ind1="1" ind2=" ">
      <subfield code="a">Wasel, Ulrike</subfield>
      <subfield code="4">trl</subfield>
    </datafield>
    <datafield tag="700" ind1="1" ind2=" ">
      <subfield code="a">Timmermann, Klaus</subfield>
      <subfield code="4">trl</subfield>
    </datafield>
    <datafield tag="700" ind1="1" ind2="2">
      <subfield code="a">Eggers, Dave</subfield>
    </datafield>
  </record>

Dave Eggers 是本书的作者, Klaus Timmermann Ulrike Wasel 帮助翻译了这本书。

在这种情况下,以下&#34;简单&#34; XPath 2.0表达式可用于提取&#34;翻译器&#34;:

/record/datafield[@tag='700'][@ind1='1'][@ind2=' ']/subfield[@code='a']/text()

此XPath 2.0表达式的结果如下:

Text='Wasel, Ulrike'
Text='Timmermann, Klaus'

这似乎很好用。 但是,我可以想到一个尚未发现的场景,其中有其他元素的类型不是翻译者(subfield[@code='a'] = 'trl'

我希望将以下选择逻辑实现为XPath 2.0,但很难构建一个:

  • /record/datafield属性tag具有价值&#34; 700&#34;
  • /record/datafield属性ind1具有值&#34; 1&#34;
  • /record/datafield属性ind2具有价值&#34; &#34;
  • /record/datafield包含subfield,其中属性code等于&#34; 4&#34;它的text()是&#34; trl&#34;

模拟场景:

<?xml version="1.0" encoding="UTF-8"?>
  <record xmlns="http://www.loc.gov/MARC21/slim" type="Bibliographic">
    <datafield tag="700" ind1="1" ind2=" ">
      <subfield code="a">Wasel, Ulrike</subfield>
      <subfield code="4">trl</subfield>
    </datafield>
    <datafield tag="700" ind1="1" ind2=" ">
      <subfield code="a">Timmermann, Klaus</subfield>
      <subfield code="4">trl</subfield>
    </datafield>
    <datafield tag="700" ind1="1" ind2=" ">
      <subfield code="a">Doe, John</subfield>
      <subfield code="4">oth</subfield>
    </datafield>
    <datafield tag="700" ind1="1" ind2="2">
      <subfield code="a">Eggers, Dave</subfield>
    </datafield>
  </record>

在这种情况下,以下&#34;简单&#34; XPath 2.0表达式可用于提取&#34;翻译器&#34;:

/record/datafield[@tag='700'][@ind1='1'][@ind2=' ']/subfield[@code='a']/text()

此XPath 2.0表达式的结果如下:

Text='Wasel, Ulrike'
Text='Timmermann, Klaus'
Text='Doe, John'

并且有错误: John Doe 不是翻译者(trl),而是该书的其他(oth)贡献者。我不想要他;)

我对MARC21-XML规范并不熟悉。我读过的有关MARC21-XML的规范是一种非常奇怪的表格格式,很难理解。 @ind1='1'@ind2=' '可能只包含翻译人员而不是&#34;类型&#34;字段用&#34; trl&#34;毫无意义。

如何构建一个XPath 2.0表达式,只选择mockedup screnario中的翻译器?

1 个答案:

答案 0 :(得分:2)

进一步限制此XPath,

/record/datafield[@tag='700'][@ind1='1'][@ind2=' ']
       /subfield[@code='a']/text()

仅选择那些datafield subfield code4元素"trl"元素的字符串值为[subfield[@code='4']='trl']的{​​{1}}元素,添加另一个谓词{{1} 1}}:

/record/datafield[@tag='700'][@ind1='1'][@ind2=' ']
                 [subfield[@code='4']='trl']
       /subfield[@code='a']/text()