XQuery / XPath:尝试根据不同节点的值返回节点

时间:2016-11-07 17:23:31

标签: xml xpath xquery

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

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

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

fagbøker=教科书

bok = book

tittel = title

forfatter = author

fornavn,mellomnavn,etternavn = forename,middlename,lastname

forlag = publisher

<?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中的发布者已经发布了其他几本书,但只有一本关于数据库,因此不应该出现在结果中。

任何人都知道如何解决这个问题?

2 个答案:

答案 0 :(得分: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>

关于!=的一个棘手的事情是,如果任何一方的任何项目不等于任何其他项目,它将返回true。所以1 != (1, 2)是正确的,因为1 != 2。如果只想在任何一方的项目不相等的情况下返回true,则使用=并将其否定。否则,只要发布商包含Database字段和其他字段,您就会收到误报。

答案 1 :(得分:1)

  

该查询应该可以找到尚未在该字段中发布图书的发布商&#34;数据库&#34;。

仅在XPath中这是微不足道和直截了当的。也许你觉得太复杂了。

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

这可以是独一无二的,并且可以在第二步中轻松排序。