You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

XQuery switch函数中case表达式对<spip:img>元素不生效问题

解决spip:img元素无法匹配switch case的问题

看起来你的问题大概率出在switch语句的语法使用错误或者命名空间/节点选择逻辑的细节上,咱们一步步拆解解决:

1. 修正Switch语句的语法(最可能的原因)

你当前的switch写法不符合标准XQuery的模式匹配规则——XQuery的switchcase后面应该跟匹配模式,而非直接写布尔表达式。虽然有些实现可能支持非标准的布尔case,但这种写法容易导致逻辑异常,也是你img分支不生效的核心原因之一。

把你的函数改成带where子句的标准模式匹配写法:

declare function p($node as element(spip:p)+, $options as map(*)) {
  switch ($node)
    case $n where exists($n/spip:img) and not($n/text()[normalize-space(.) != ''])
      return passthru($n, $options)
    case $n where exists($n/spip:figure) and not($n/text()[normalize-space(.) != ''])
      return passthru($n, $options)
    case $n where exists($n/spip:blockquote) and not($n/text()[normalize-space(.) != ''])
      return passthru($n, $options)
    default
      return <para>
               <alinea>{ passthru($node, $options) }</alinea>
             </para>
};

这里用exists($n/spip:img)替代instance of,直接检查spip:p下是否存在spip:img子元素,逻辑更清晰且更可靠。

2. 确认命名空间绑定与元素实际命名空间一致

你提到XML是带有spip命名空间的,但示例中写的是<p><img/></p>——要确保:

  • XML中的img元素确实带有spip前缀(即<spip:img/>),并且属于正确的spip命名空间;
  • 你的XQuery prolog中已经正确声明了spip命名空间,比如:
    declare namespace spip = "http://your-spip-namespace-uri";
    

如果img元素没有使用spip命名空间,那$n/spip:img会找不到节点,自然无法匹配case。

3. 简化文本节点检查逻辑

你当前的文本检查fn:not($node/text()[fn:normalize-space(.) != ''])可以简化为not(normalize-space($node/text())),效果一致但更易读:

case $n where exists($n/spip:img) and not(normalize-space($node/text()))

4. 备选方案:改用if-then-else(既然你说这个逻辑在if里有效)

如果switch的模式匹配还是有问题,直接换成你验证过的if-then-else写法,逻辑更直观:

declare function p($node as element(spip:p)+, $options as map(*)) {
  if (exists($node/spip:img) and not(normalize-space($node/text()))) then
    passthru($node, $options)
  else if (exists($node/spip:figure) and not(normalize-space($node/text()))) then
    passthru($node, $options)
  else if (exists($node/spip:blockquote) and not(normalize-space($node/text()))) then
    passthru($node, $options)
  else
    <para>
      <alinea>{ passthru($node, $options) }</alinea>
    </para>
};

你可以先尝试修正switch的语法,这应该能解决大部分问题。如果还是不行,检查命名空间是否匹配,或者直接改用if-then-else写法。

内容的提问来源于stack exchange,提问作者laconis

火山引擎 最新活动