【问题标题】:XQuery/XPath: Trying to return a node based on the value of a different nodeXQuery/XPath:尝试根据不同节点的值返回一个节点
【发布时间】:2016-11-07 17:23:31
【问题描述】:

我正在尝试编写一个查询,该查询根据同一父节点中是否存在特定字符串返回一个节点。

我的 XML 示例,它有一个根元素“books”,让您了解它的外观。

编辑:添加了更大的数据。省略了“bok”的一些子元素,因为它们不相关。 这是挪威语,如果您想知道的话:

fagbøker = 教科书

bok = 书

title = 标题

forfatter = 作者

fornavn, mellomnavn, etternavn = 名字、中间名、姓氏

forlag = 发布者

<?xml version="1.0" encoding="UTF-8"?>

<?xml-model href="Fagb%C3%B8ker.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?>
<fagbøker>
  <bok isbn="9780321197849">
    <tittel>An Introduction to Database Systems</tittel>
    <forfatter>
        <fornavn>Christopher</fornavn>
        <mellomnavn>J.</mellomnavn>
        <etternavn>Date</etternavn>
    </forfatter>
    <fagfelt>
        <felt>Databaser</felt> 
    </fagfelt>
    <forlag>Pearson</forlag>
</bok>

<bok isbn="9780321392794">
    <tittel>Data Structures in Java: From Abstract Data Types to the Java Collections
        Framework</tittel>
    <forfatter>
        <fornavn>Simon</fornavn>
        <etternavn>Gray</etternavn>
    </forfatter>
    <fagfelt>
        <felt>Programmering</felt>
    </fagfelt>
    <forlag>Pearson</forlag>

</bok>

<bok isbn="0321165810">
    <tittel>XQuery: The XML Query Language</tittel>
    <forfatter>
        <fornavn>Brundage</fornavn>
        <etternavn>Michael</etternavn>
    </forfatter>
    <fagfelt>
        <felt>XML</felt>
    </fagfelt>
    <forlag>Addison-Wesley Professional</forlag>
</bok>

<bok isbn="0201730472">
    <tittel>Discrete Mathematics for Computing</tittel>
    <forfatter>
        <fornavn>Rod</fornavn>
        <etternavn>Haggarty</etternavn>
    </forfatter>
    <fagfelt>
        <felt>Matematikk</felt>
    </fagfelt>
    <forlag>Addison-Wesley Professional</forlag>
</bok>

<bok isbn="0321417461">
    <tittel>Prolog Programming for Artificial Intelligence</tittel>
    <forfatter>
        <fornavn>Ivan</fornavn>
        <etternavn>Bratko</etternavn>
    </forfatter>
    <fagfelt>
        <felt>Kunstig intelligens</felt>
    </fagfelt>
    <forlag>Pearson Education Canada</forlag>
</bok>

<bok isbn="3540126899">
    <tittel>A Programming Logic</tittel>
    <forfatter>
        <fornavn>Robert</fornavn>
        <mellomnavn>L.</mellomnavn>
        <etternavn>Constable</etternavn>
    </forfatter>
    <fagfelt>
        <felt>Programmering</felt>
    </fagfelt>
    <forlag>Springer-Verlag London LTD</forlag>
 </bok>
</fagbøker>

该查询应该在“数据库”字段中查找尚未出版书籍的出版商。我的 XML 中还有其他几本与数据库无关的书籍,以及尚未在该领域发表任何内容的出版商。

 for $publisher in distinct-values(
 let $doc := doc('../Fagboker.xml')
 where every $field in $doc
    satisfies $field//fieldname != 'Database'
 return
    $doc//publisher)

 return
    <publisher>{$publisher}</publisher>

这会返回我拥有的每个发布者。上面 XML 中的发布者是我不希望出现在结果中的唯一发布者。上述 XML 中的出版商已经出版了其他几本书,但只有一本关于数据库,因此它不应该出现在结果中。

有人知道我该如何解决这个问题吗?

【问题讨论】:

    标签: xml xpath xquery


    【解决方案1】:

    问题是,如果任何一个发布者匹配,您将在此处返回数据库中的每个发布者:

    ...
    return
      $doc//publisher)
    

    相反,您可以遍历每个不同的发布者名称,然后仅按字段不包含 Database 的发布者进行过滤:

    let $doc := doc('../Fagboker.xml')
    for $publisher in distinct-values($doc//forlag)
    where (
      every $field in $doc//bok[forlag = $publisher]//fagfelt
      satisfies not($field//felt = 'Databaser')
      ) 
    return <publisher>{$publisher}</publisher>
    

    返回:

    <publisher>Addison-Wesley Professional</publisher>
    <publisher>Pearson Education Canada</publisher>
    <publisher>Programmering</publisher>
    

    关于!= 需要注意的一件棘手的事情是,如果任一侧的 any 项不等于任何其他项,它将返回 true。所以1 != (1, 2) 是真的,因为1 != 2。如果您只想在两边都没有相等的项目时才返回 true,则使用 = 并否定它。否则,只要发布者包含 Database 字段和另一个字段,您就会得到误报。

    【讨论】:

    • 谢谢。不过,此查询返回的 XML 与我的完全相同。开始认为我的 XML 有问题,只是看不出它可能是什么。
    • 您需要共享更多的测试数据。否则就不可能了
    • @Sebastian 当我更新测试数据并查询您的更改时,它似乎返回了您要求的输出。
    • 谢谢!出于某种原因,我的 let 表达式有一点点不同。我对 XML/Xquery 完全陌生,所以这些小事情有时会让我忘记。
    【解决方案2】:

    该查询应该在“数据库”字段中查找尚未出版书籍的出版商。

    这仅在 XPath 中是简单而直接的。可能你想的太复杂了。

    $doc//publisher[not(../field = 'Database')]
    

    这可以在第二步中变得独一无二并轻松排序。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多