代码之家  ›  专栏  ›  技术社区  ›  burnersk

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

  •  2
  • burnersk  · 技术社区  · 6 年前

    我有一些关于书籍的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>
    

    戴夫·艾格斯 是这本书的作者 克劳斯·蒂默尔曼 乌尔里克瓦塞尔 帮助翻译这本书。

    在此场景中,以下“简单”XPath 2.0表达式可用于提取“转换器”:

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

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

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

    这似乎很有效。 然而 ,我可以想到一个尚未发现的场景,其中有其他元素的类型不是translator( subfield[@code='a'] = 'trl' .

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

    • /record/datafield 属性 tag 值为“700”
    • /记录/数据字段 属性 ind1 具有值“1”
    • /记录/数据字段 属性 ind2 具有值“”
    • /记录/数据字段 包含 subfield 带属性 code 等于“4”及其 text() 为“trl”

    要模拟场景,请执行以下操作:

    <?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>
    

    在此场景中,以下“简单”XPath 2.0表达式可用于提取“转换器”:

    /记录/数据字段[@tag='700'][@ind1='1'][@ind2='']/子字段[@code='a']/文本()
    

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

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

    还有一个错误: 约翰·多伊 不是翻译( trl )但是其他一些( oth )这本书的作者。我不要他;)

    我不太熟悉MARC21-XML规范。我读到的关于MARC21-XML的规范是一种非常奇怪的表格格式,很难理解。有可能 @ind1='1' @ind2=' ' 仅包含翻译器,但带有“trl”的“type”字段没有意义。

    如何构造一个XPath 2.0表达式,只从mockedup screnario中选择转换器?

    1 回复  |  直到 6 年前
        1
  •  2
  •   kjhughes    6 年前

    要进一步限制此XPath,

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

    仅选择那些 datafield subfield 具有的子元素 code 属于 4 字符串值为 "trl" ,添加另一个谓词, [subfield[@code='4']='trl'] :

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