在自己接近這個問題時,我可能會嘗試在首次創建NCX文件時生成正確的值。但是,如果面臨的挑戰是如何在一個文件中修復playOrder
屬性,其中的值充滿了空值,虛擬屬性或其他不正確的屬性,我可以考慮兩種技術:使用XQuery類型切換表達式遍歷文檔中的所有節點並交換所需的值,或者使用XQuery Update來手術更新值。在下面的每個示例中,兩者都採用相同的方法:使用ancestor
和preceding
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更新實現,它要求文件存儲在數據庫中。結果文件與上述結果相同。
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之一的替代方法是使用'index-of(// navPoints,$ navPoint)' – joewiz
您的解決方案非常複雜,我必須將其標記爲答案。其實,我最終使用的解決方案只是'playOrder =「{count($ h1/preceding :: xhtml:li)+ 1}」''$ h1'是標題的變量,接下來它將是' $ h2'等等。爲了方便起見,我將添加另一個答案。 –
這個圖很棒!我剛把它貼在我的LCD上! –