如何在XQuery中获得最常用的属性?

时间:2013-10-20 21:09:38

标签: xpath xquery

我的XML数据包含许多具有type属性的<ref>个元素。我想为每个文件获得最流行的类型,但似乎无法弄清楚...现在我有

for $song in collection('/db/course/rap/data')
let $types := distinct-values($song//ref/@type)
for $type in $types
let $freq := count($song//ref[@type=$type])
order by $freq descending
return concat($song//title/string(), ' ', $type, ' ', $freq)

它给出了歌曲的名称(标题元素),以及该歌曲中每种类型的频率值。但是,我只对每个中最受欢迎的项目感兴趣。我已经尝试了很长时间,但不能提出任何有意义的事情......

示例:

<song>
<header>
    <title>Восток</title>
    <artist>25/17 п.у. Саграда</artist>
    <album>Межсезонье</album>
    <accessDate>09/16/2013</accessDate>
    <source href="http://vk.com/audio?performer=1&q=25%2F17"/>
</header>
<lyrics>
    <stanza>
        <line n="1"><ref type="home" value="neut">Моя земля</ref>, <ref type="war" value="neut"
                >пропитана кровью</ref> до магмы,</line>
        <line n="2">Я видел <ref type="war" value="neut">флагман</ref> под небесным Андреевским
            флагом.</line>
        <line n="3">Женщины плакали, <ref type="war" value="neut">эскадра выходила в море</ref>.
            Оно так и не возвратило лейтенанта домой,</line>
        <line n="4"><ref type="war" value="neut">Эсминец принял бой, был потоплен</ref>. То ли
            мины, то ли в баках рвануло топливо.</line>
        <line n="5">А Севастополь ждал назад и верил искренне, шагами меряя пространство
            Графской пристани,</line>
        <line n="6">И если пристально смотреть в сторону востока, то можно разглядеть и флаги на
            флагштоках,</line>
        <line n="7">погибших кораблей, ведь <ref type="soul" value="pos">через 9 дней их души
                отлетают в небо как и у людей</ref>.</line>
        <line n="8">
            <ref type="home" value="neg">Но Черноморский флот уже не тот, чужие корабли проходят
                мимо Инкерманских высот,</ref>
        </line>
        <line n="9">за горизонт, в эти закаты алые, пока гробницы стерегут прах
            адмиралов.</line>
        <line n="10">Я и не знал, что значит надпись не по нашему , на именном оружии ,
            расстрелянного маршала,</line>
        <line n="11">и почему <ref type="war" value="pos">всё то, что было завоевано</ref> пошло
                <swear>проёбом</swear>. Или мы сами предаём это?</line>
        <line n="12"><ref type="war" value="neg"><ref type="home" value="neg">Районы</ref>, как
                театр военных действий</ref>, тут <ref type="drugs">опиаты</ref> рано обрывают
            детство.</line>
        <line n="13">Врачи лупили по щекам, мне говорили, дыши, <ref value="pos">ведь все они
                погибли, ради того чтобы ты жил</ref>!</line>
    </stanza>
    <stanza type="chorus">
        <line n="14">На свет из тени, из подземелий на воздух.</line>
        <line n="15">Пока есть время и силы, пока ещё не поздно.</line>
        <line n="16">Ещё не познанный, мой ориентир.</line>
        <line n="17">Я вижу грозный, прекрасный, яростный мир.</line>
        <line n="18">На свет из тени, из подземелий на воздух.</line>
        <line n="19">Пока есть время и силы, пока ещё не поздно.</line>
        <line n="20">Ещё не познанный, мой ориентир.</line>
        <line n="21">Я вижу грозный, прекрасный, яростный мир.</line>
    </stanza>
    <stanza>
        <line n="22">Учебник по истории, подобный девке площадной, готов отдаться <ref
                type="politics" value="neg">каждому, кто завладел казной</ref>.</line>
        <line n="23"><ref type="politics" value="neg">В очередной войне за трон</ref>, <ref
                type="econ" value="neg">станок печатает тираж</ref> , <ref value="politics"
                type="neg">кто защищал свой порт, а кто кричал «На абордаж».</ref></line>
        <line n="24">Уже не важно, важно кто за это платит, кто подливает в твой бокал и
            покупает платье.</line>
        <line n="25">Ломала каблуки, хмельная, в страстном танце, потом за школой, <ref
                type="sex">тебя имели иностранцы.</ref></line>
        <line n="26">
            <ref type="russia">Шептала, «Всех люблю, всем хватит места», а ведь когда то ты
                мечтала быть невестой.</ref>
        </line>
        <line n="27">Семья. Сын учится ходить хватаясь за подол. Сейчас ты на коленях за арбуз.
            Тебе не западло?</line>
        <line n="28">И кто тебя поднимет, ведь ты сама не хочешь.</line>
        <line n="29"><ref type="family">Отец</ref> сгорел от горя, ты в бреду хохочешь.</line>
        <line n="30">Переписать учебник. Смыть с тебя всю грязь.</line>
        <line n="31">Слезами. Потом с кровью. В очередной раз.</line>
    </stanza>
    <stanza type="chorus">
        <line n="32">На свет из тени, из подземелий на воздух.</line>
        <line n="33">Пока есть время и силы, пока ещё не поздно.</line>
        <line n="34">Ещё не познанный, мой ориентир.</line>
        <line n="35">Я вижу грозный, прекрасный, яростный мир.</line>
        <line n="36">На свет из тени, из подземелий на воздух.</line>
        <line n="37">Пока есть время и силы, пока ещё не поздно.</line>
        <line n="38">Ещё не познанный, мой ориентир.</line>
        <line n="39">Я вижу грозный, прекрасный, яростный мир.</line>
    </stanza>
    <stanza type="chorus">
        <line n="40">На свет из тени, из подземелий на воздух.</line>
        <line n="41">Пока есть время и силы, пока ещё не поздно.</line>
        <line n="42">Ещё не познанный, мой ориентир.</line>
        <line n="43">Я вижу грозный, прекрасный, яростный мир.</line>
        <line n="44">На свет из тени, из подземелий на воздух.</line>
        <line n="45">Пока есть время и силы, пока ещё не поздно.</line>
        <line n="46">Ещё не познанный, мой ориентир.</line>
        <line n="47">Я вижу грозный, прекрасный, яростный мир.</line>
    </stanza>
</lyrics>

如果我们假设这首歌有20个战争参考和5个灵魂参考(实际上没有计算),那么所需的输出将是歌曲名称(标题元素)和最流行的指示(战争)。

2 个答案:

答案 0 :(得分:1)

将每首歌曲的结果数限制为一个:

for $song in collection('/db/course/rap/data')
let $types := distinct-values($song//ref/@type)
return (
  for $type in $types
  let $freq := count($song//ref[@type=$type])
  order by $freq descending
  return concat($song//title/string(), ' ', $type, ' ', $freq)
)[1]

答案 1 :(得分:0)

看起来像下面的部分(未经测试)会让你最频繁。可能有更有效,更好的方式。

let $songs := collection('/db/course/rap/data')
return
    (
    for $type in $songs//ref[@type]
    let $freq := count($songs//ref[@type=$type])
    order by $freq descending
    return ($t, $freq)
    )[1]