gpt4 book ai didi

xpath - 如何在 XQuery 中的 NCX 文件(用于 epub)中生成正确的 playOrder?

转载 作者:行者123 更新时间:2023-12-03 16:15:50 26 4
gpt4 key购买 nike

我为一件非常具体的事情而苦恼——为 epub 生成 NCX 文件。问题出在 playOrder每个 navPoint 的属性元素,因为数字通常只是增加而没有任何嵌套的重要性。另一方面,该文件是通过迭代嵌套元素自然生成的(这拒绝了 at $count 计数样式的简单用法)。我尝试通过迭代 来生成它数组 直接的章节,我尝试从准备好的 toc 生成它文件(也许更容易,因为我遍历一个节点,而不是数组)。问题是一样的。

NCX 文件的示例部分:

<ncx xmlns="http://www.daisy.org/z3986/2005/ncx/" version="2005-1">
<head>
<meta name="dtb:uid" content=""/>
<meta name="dtb:depth" content="1"/>
<meta name="dtb:totalPageCount" content="0"/>
<meta name="dtb:maxPageNumber" content="0"/>
</head>
<docTitle>
<text/>
</docTitle>
<navMap>
<navPoint id="title-page" playOrder="1">
<navLabel>
<text>Title Page</text>
</navLabel>
<content src="title-page.xhtml"/>
</navPoint>
<navPoint id="chapter-1.xhtml#anch1lev1" playOrder="@@@">
<navLabel>
<text>ÚVOD</text>
</navLabel>
<content src="chapter-1.xhtml#anch1lev1"/>
<navPoint id="chapter-1.xhtml#anch2lev1" playOrder="@@@">
<navLabel>
<text>Přehled bádání nad nálezy terry sigillaty v Čechách</text>
</navLabel>
<content src="chapter-1.xhtml#anch2lev1"/>
</navPoint>
<navPoint id="chapter-1.xhtml#anch2lev2" playOrder="@@@">
<navLabel>
<text>Poválečné bádání nad nálezy terry sigillaty v evropském barbariku</text>
</navLabel>
<content src="chapter-1.xhtml#anch2lev2"/>
</navPoint>
<navPoint id="chapter-1.xhtml#anch2lev3" playOrder="@@@">
<navLabel>
<text>Terminologie a tvarová klasifikace</text>
</navLabel>
<content src="chapter-1.xhtml#anch2lev3"/>
</navPoint>
</navPoint>
<navPoint id="chapter-2.xhtml#anch1lev1" playOrder="@@@">
<navLabel>
<text>KATALOG</text>
</navLabel>
<content src="chapter-2.xhtml#anch1lev1"/>
<navPoint id="chapter-2.xhtml#anch2lev1" playOrder="@@@">
<navLabel>
<text>Struktura a metodické pojetí katalogu</text>
</navLabel>
<content src="chapter-2.xhtml#anch2lev1"/>
</navPoint>
<navPoint id="chapter-2.xhtml#anch2lev2" playOrder="@@@">
<navLabel>

这里我有 playOrder属性仅作为占位符。有没有一些简单的方法来替换 @@@只需增加计数器(每个 navPoint )?我试过 typeswitch (无法使其工作)和对前面的标题级别的详尽计数 - 它有效但为 非常随着标题级别的增加,笨拙和缓慢,并且由于 xpath 轴的细微变化,文档之间非常不稳定。我需要一种简单、防弹的方法。我想计算之前的许多级别不是正确的选择。

最佳答案

在我自己解决这个问题时,我可能会在第一次创建 NCX 文件时尝试生成正确的值。但如果挑战是如何修复 playOrder如果文件中的属性值充满了空、虚拟或其他不正确的属性,我可以想到两种技术:使用 XQuery typeswitch 表达式遍历文档中的所有节点并交换所需的值,或者使用 XQuery更新以手术更新值。在下面的每个示例中,都采用相同的方法:使用 ancestorpreceding XPath 轴计算 playOrder 的值属性。注意:我对示例 XML 的唯一更改是关闭最终元素以使其格式正确。

更新 : 在我的第一个版本中,我错误地省略了 ancestor轴计数,导致不正确的值。我忘记了 preceding轴不包括 ancestor轴。从我最喜欢的 XPath 轴图 https://our.umbraco.org/media/upload/0562fd58-c6db-4fa8-a432-68b28f11c3f2/rs/7x1B0.gif 中可以清楚地看到这一点。 .

xquery version "3.0";

declare namespace ncx="http://www.daisy.org/z3986/2005/ncx/";

declare function local:fix-playorder($nodes as item()*) {
for $node in $nodes
return
typeswitch ($node)
case element(ncx:navPoint) return
<navPoint xmlns="http://www.daisy.org/z3986/2005/ncx/">{
$node/@*[not(name(.) = 'playOrder')],
attribute playOrder { count($node/ancestor::ncx:navPoint) + count($node/preceding::ncx:navPoint) + 1 },
local:fix-playorder($node/node())
}</navPoint>
case element() return
element {node-name($node)} {$node/@*, local:fix-playorder($node/node())}
default return
$node
};

let $ncx :=
<ncx xmlns="http://www.daisy.org/z3986/2005/ncx/" version="2005-1">
<head>
<meta name="dtb:uid" content=""/>
<meta name="dtb:depth" content="1"/>
<meta name="dtb:totalPageCount" content="0"/>
<meta name="dtb:maxPageNumber" content="0"/>
</head>
<docTitle>
<text/>
</docTitle>
<navMap>
<navPoint id="title-page" playOrder="1">
<navLabel>
<text>Title Page</text>
</navLabel>
<content src="title-page.xhtml"/>
</navPoint>
<navPoint id="chapter-1.xhtml#anch1lev1" playOrder="@@@">
<navLabel>
<text>ÚVOD</text>
</navLabel>
<content src="chapter-1.xhtml#anch1lev1"/>
<navPoint id="chapter-1.xhtml#anch2lev1" playOrder="@@@">
<navLabel>
<text>Přehled bádání nad nálezy terry sigillaty v Čechách</text>
</navLabel>
<content src="chapter-1.xhtml#anch2lev1"/>
</navPoint>
<navPoint id="chapter-1.xhtml#anch2lev2" playOrder="@@@">
<navLabel>
<text>Poválečné bádání nad nálezy terry sigillaty v evropském barbariku</text>
</navLabel>
<content src="chapter-1.xhtml#anch2lev2"/>
</navPoint>
<navPoint id="chapter-1.xhtml#anch2lev3" playOrder="@@@">
<navLabel>
<text>Terminologie a tvarová klasifikace</text>
</navLabel>
<content src="chapter-1.xhtml#anch2lev3"/>
</navPoint>
</navPoint>
<navPoint id="chapter-2.xhtml#anch1lev1" playOrder="@@@">
<navLabel>
<text>KATALOG</text>
</navLabel>
<content src="chapter-2.xhtml#anch1lev1"/>
<navPoint id="chapter-2.xhtml#anch2lev1" playOrder="@@@">
<navLabel>
<text>Struktura a metodické pojetí katalogu</text>
</navLabel>
<content src="chapter-2.xhtml#anch2lev1"/>
</navPoint>
<navPoint id="chapter-2.xhtml#anch2lev2" playOrder="@@@">
<navLabel/>
</navPoint>
</navPoint>
</navMap>
</ncx>
return
local:fix-playorder($ncx)

结果:
<ncx xmlns="http://www.daisy.org/z3986/2005/ncx/" version="2005-1">
<head>
<meta name="dtb:uid" content=""/>
<meta name="dtb:depth" content="1"/>
<meta name="dtb:totalPageCount" content="0"/>
<meta name="dtb:maxPageNumber" content="0"/>
</head>
<docTitle>
<text/>
</docTitle>
<navMap>
<navPoint id="title-page" playOrder="1">
<navLabel>
<text>Title Page</text>
</navLabel>
<content src="title-page.xhtml"/>
</navPoint>
<navPoint id="chapter-1.xhtml#anch1lev1" playOrder="2">
<navLabel>
<text>ÚVOD</text>
</navLabel>
<content src="chapter-1.xhtml#anch1lev1"/>
<navPoint id="chapter-1.xhtml#anch2lev1" playOrder="3">
<navLabel>
<text>Přehled bádání nad nálezy terry sigillaty v Čechách</text>
</navLabel>
<content src="chapter-1.xhtml#anch2lev1"/>
</navPoint>
<navPoint id="chapter-1.xhtml#anch2lev2" playOrder="4">
<navLabel>
<text>Poválečné bádání nad nálezy terry sigillaty v evropském barbariku</text>
</navLabel>
<content src="chapter-1.xhtml#anch2lev2"/>
</navPoint>
<navPoint id="chapter-1.xhtml#anch2lev3" playOrder="5">
<navLabel>
<text>Terminologie a tvarová klasifikace</text>
</navLabel>
<content src="chapter-1.xhtml#anch2lev3"/>
</navPoint>
</navPoint>
<navPoint id="chapter-2.xhtml#anch1lev1" playOrder="6">
<navLabel>
<text>KATALOG</text>
</navLabel>
<content src="chapter-2.xhtml#anch1lev1"/>
<navPoint id="chapter-2.xhtml#anch2lev1" playOrder="7">
<navLabel>
<text>Struktura a metodické pojetí katalogu</text>
</navLabel>
<content src="chapter-2.xhtml#anch2lev1"/>
</navPoint>
<navPoint id="chapter-2.xhtml#anch2lev2" playOrder="8">
<navLabel/>
</navPoint>
</navPoint>
</navMap>
</ncx>

XQuery 更新方法将使用相同的 preceding轴技术。我这里的示例是针对 eXist 的 XQuery Update 实现的,它要求将文件存储在数据库中。生成的文档与上述结果相同。
xquery version "3.0";

declare namespace ncx="http://www.daisy.org/z3986/2005/ncx/";

let $ncx :=
<ncx xmlns="http://www.daisy.org/z3986/2005/ncx/" version="2005-1">
<head>
<meta name="dtb:uid" content=""/>
<meta name="dtb:depth" content="1"/>
<meta name="dtb:totalPageCount" content="0"/>
<meta name="dtb:maxPageNumber" content="0"/>
</head>
<docTitle>
<text/>
</docTitle>
<navMap>
<navPoint id="title-page" playOrder="1">
<navLabel>
<text>Title Page</text>
</navLabel>
<content src="title-page.xhtml"/>
</navPoint>
<navPoint id="chapter-1.xhtml#anch1lev1" playOrder="@@@">
<navLabel>
<text>ÚVOD</text>
</navLabel>
<content src="chapter-1.xhtml#anch1lev1"/>
<navPoint id="chapter-1.xhtml#anch2lev1" playOrder="@@@">
<navLabel>
<text>Přehled bádání nad nálezy terry sigillaty v Čechách</text>
</navLabel>
<content src="chapter-1.xhtml#anch2lev1"/>
</navPoint>
<navPoint id="chapter-1.xhtml#anch2lev2" playOrder="@@@">
<navLabel>
<text>Poválečné bádání nad nálezy terry sigillaty v evropském barbariku</text>
</navLabel>
<content src="chapter-1.xhtml#anch2lev2"/>
</navPoint>
<navPoint id="chapter-1.xhtml#anch2lev3" playOrder="@@@">
<navLabel>
<text>Terminologie a tvarová klasifikace</text>
</navLabel>
<content src="chapter-1.xhtml#anch2lev3"/>
</navPoint>
</navPoint>
<navPoint id="chapter-2.xhtml#anch1lev1" playOrder="@@@">
<navLabel>
<text>KATALOG</text>
</navLabel>
<content src="chapter-2.xhtml#anch1lev1"/>
<navPoint id="chapter-2.xhtml#anch2lev1" playOrder="@@@">
<navLabel>
<text>Struktura a metodické pojetí katalogu</text>
</navLabel>
<content src="chapter-2.xhtml#anch2lev1"/>
</navPoint>
<navPoint id="chapter-2.xhtml#anch2lev2" playOrder="@@@">
<navLabel/>
</navPoint>
</navPoint>
</navMap>
</ncx>
let $store := xmldb:store('/db', 'test.ncx', $ncx)
let $doc := doc('/db/test.ncx')
for $navPoint in $doc//ncx:navPoint
return
update value $navPoint/@playOrder with (count($node/ancestor::ncx:navPoint) + count($navPoint/preceding::ncx:navPoint) + 1)

关于xpath - 如何在 XQuery 中的 NCX 文件(用于 epub)中生成正确的 playOrder?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38015984/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com