gpt4 book ai didi

xml - 将纯文本 block 包裹在 P 中,同时跳过已经包裹在 P 中的 block

转载 作者:行者123 更新时间:2023-12-04 07:44:18 25 4
gpt4 key购买 nike

我需要用段落包装所有纯文本块,但可能有一个嵌套的段落应该被跳过。我将如何解决这个问题?
我很难理解如何在跳过现有段落的同时将一些纯文本包装成一个段落。
给定 XML:

<section xmlns="http://www.w3.org/1999/xhtml">    
<div>
test test
<p>test</p>
<ins>INS</ins>
text
</div>
</section>
预期结果:
<section xmlns="http://www.w3.org/1999/xhtml">    
<div>
<p>test test</p>
<p>test</p>
<p>
<ins>INS</ins>
text
</p>
</div>
</section>

最佳答案

这是一种使用简单递归算法通过 p 个节点有效划分 div 内容的方法

declare default element namespace "http://www.w3.org/1999/xhtml";

declare function local:collect($sequence as node()*) as node()* {
(: index of last p in this candidate subsequence :)
let $nextP := max((0,
(for $i in (1 to count($sequence))
where $sequence[$i][self::p]
return $i)))
return
(: if sequence is empty then return empty sequence :)
if(count($sequence) = 0) then ()
(: if no p in this candidate subsequence, then wrap it in a p :)
else if($nextP = 0) then <p>{$sequence}</p>
(: otherwise evaluate subsequence before the last p, the p,
and the subsequence after the last p
:)
else (
local:collect(subsequence($sequence,1,$nextP - 1)),
$sequence[$nextP],
local:collect(subsequence($sequence,$nextP + 1))
)
};

let $input :=
<section>
<div>
test test
<p>test</p>
<ins>INS</ins>
text
</div>
</section>
return
<section>
{
for $div in $input/div
return <div>{local:collect($div/(*|text()))}</div>
}
</section>
产生以下结果:
<section xmlns="http://www.w3.org/1999/xhtml">
<div>
<p>
test test
</p>
<p>test</p>
<p><ins>INS</ins>
text
</p>
</div>
</section>
您的预期结果与文本节点中的前导/尾随空格不一致。目前尚不清楚您是否真的希望获得针对某些文本而不是其他文本规范化空格的确切结果。可能不是。
要标准化所有文本节点中的空白,请替换以下内容:
<p>{$sequence}</p>
和:
<p>{for $x in $sequence return if($x[self::text()]) then normalize-space($x) else ($x)}</p>
产生:
<section xmlns="http://www.w3.org/1999/xhtml">
<div>
<p>test test</p>
<p>test</p>
<p><ins>INS</ins>text</p>
</div>
</section>
当没有 p 或多个 p 时,这里的算法有效,但我没有测试每个场景。
在 XQuery 3 中,这可以通过滚动窗口来简化,例如:
(: Return true if the passed nodes exist and both p or neither are p.
:)
declare function local:same($compare1 as node()?, $compare2 as node()?) as xs:boolean {
if(not($compare1) or not($compare2)) then false()
else if(($compare1[self::p] and $compare2[self::p])
or (not($compare1[self::p]) and not($compare2[self::p])))
then true()
else false()
};

let $input :=
<section>
<div>
test test
<p>test</p>
<ins>INS</ins>
text
</div>
</section>

return
<section>
{
for $div in $input/div
return
<div>
{
for tumbling window $partition in $div/(*|text())
start $s previous $s-prev when not(local:same($s, $s-prev))
end $e next $e-next when not(local:same($e, $e-next))
return
if($partition[1][self::p])
then $partition
else <p>{$partition}</p>
}
</div>
}
</section>
与标准化空间类似,替换:
<p>{$partition}</p>
<p>{for $x in $partition return if($x[self::text()]) then normalize-space($x) else ($x)}</p>

关于xml - 将纯文本 block 包裹在 P 中,同时跳过已经包裹在 P 中的 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67274583/

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