【问题标题】:Autoincremental auxiliar index var for XQuery nested loops (w. dynamical count)XQuery 嵌套循环的自动增量辅助索引变量(带有动态计数)
【发布时间】:2012-07-03 13:08:58
【问题描述】:

我想要一个解决方案来了解如何在 xQuery 中将真正的循环计数器保存为 Java,而不是针对我的特定简化演示的解决方法。我知道在 xQuery 3.0 中有一个用于 FLOWR 结构的 count 保留字,但它在 Saxon 9.something 之前没有用。这是我的例子。

     for $elem at $x in /Data/* return element Elem {       
            attribute Name   {concat('_',$x,'.',name($elem))},      
            (: ...10 lines of code... :)        
            for $subelem at $y in $elem/*       
            (: ...5 lets... :)      
            return element SubElemen {
               attribute Name {concat('_',$x,'.',$y,'_',name($subelement))},
               (...20 lines of other attrs and elements ...)
           for $subsubelem at $z in $subElem/SubSubElement
               let $absIterIndex := 'THIS IS WHAT IM LOOKING'
               let $subSubElemName := concat('_',$absIterIndex,'_',name($subElem))
            return
                                 element SubSubElem {
                 attribute Name {$subsubelem}, 
                   (..100 lines more playing with $x, $y, $absIterIndex, all lets for that iteration, attributes depending on them...)

输出是这样的(隐藏和简化的真实数据)

 <Elem Name="_1.Name">
      <SubElem Name="_1.1_Name">
           <SubSubElem Name="_1.First"/>
           <SubSubElem Name="_2.Second"/>
           <SubSubElem Name="_3.Third"/>
      </SubElem Name="_1.1_Name">
      <SubElem Name="_1.2_Name">
           <SubSubElem Name="_4.Fourth"/>
           <SubSubElem Name="_5.Fifth"/>
           <SubSubElem Name="_6.Sixth"/>
           <SubSubElem Name="_7.Seventh"/>
      </SubElem Name="_1.1_Name">
  <Elem Name="_2.Name">
      <SubElem Name="_2.1_Name">
           <SubSubElem Name="_8.Eighth"/>
           <SubSubElem Name="_9.Ninth"/>
           <SubSubElem Name="_10.Tenth"/>
           <SubSubElem Name="_11.Eleventh"/>
      </SubElem Name="_2.1_Name">
      <SubElem Name="_2.2_Name"/>
  </Elem Name="_2.Name">
  <Elem Name="_3.Name">
      <SubElem Name="_3.1_Name">
           <SubSubElem Name="_12.Twelven"/>
      </SubElem Name="_3.1_Name">
      <SubElem Name="_3.2_Name"/>
  </Elem Name="_3.Name">     

这是上一个问题Autoincremental auxiliar index var for XQuery nested loops 的扩展,我接受了 xQuery 3.0 计数器的解决方案,然后提出了手动执行此操作的替代方案。但是知道我认为这个观点是不同的,更具体的,还有一个新的例子。如果您认为应该删除它,请告诉我。

【问题讨论】:

  • 这个问题很模糊 -- 请编辑问题并提供一个完整(但尽可能小)的示例:XML 文档、确切想要的结果、查询的要求必须实施。
  • user1352530:如果问题是具体的,我可以为您提供帮助——因为它是一般的,必须做很多猜测(并且对这个猜测的正确性)在构建一个演示示例来展示该技术。
  • user1352530:我发现这个问题根本不能说明你想要表达的实际问题——这个特定的问题有一个非常简单的解决方案——只需输出数字 1 到 N,其中 N 是所有非空白字符的计数。
  • 如您所见,这个“演示”过于简单,并没有为我们提供任何问题的定义。我仍然不确定你真正想要什么。您没有代表性示例这一事实可能意味着您没有清楚地了解问题所在。换句话说:一个“问题”不存在的具体例子不是问题。
  • 最后一次编辑清楚地显示了您想要什么,而您想要某些东西这一事实并不意味着存在任何需要解决所需功能的问题。我现在更加确信这个问题不是基于任何真正的问题。我的预测是,您向我们展示的任何支持所需功能的问题,如果没有此功能,都会有解决方案。但你要证明我错了:)

标签: xml loops iteration xquery counter


【解决方案1】:

您可以做的是在嵌套迭代的结果序列上添加一个额外的传递,即

declare variable $script := 'abc defg h ijklm nop 
                                 qrs tu vw
                                 xy z';
for $letter at $lettersTotal in
(
  for $line at $numLine in tokenize($script, '(\r\n?|\n\r?)')
  for $word at $numWord in tokenize(normalize-space($line),' ')
  for $codepoint at $numLetter in string-to-codepoints($word)
  return codepoints-to-string($codepoint)
)
return ($lettersTotal, $letter)

返回

1 a 2 b 3 c 4 d 5 e 6 f 7 g 8 h 9 i 10 j 11 k 12 l 13 m 14 n 15 o 16 p 17 q 18 r 19 s 20 t 21 u 22 v 23 w 24 x 25 y 26 z

如果幸运的话,您的 XQuery 处理器可以流式传输结果而无需具体化序列。

【讨论】:

  • 这是一个非常好的主意!但它有一个重要的缺点。您不能在当前迭代中使用计数器,即 90% 的使用次数。这就像将它传递给 count()。谢谢!
  • 好的,所以用return concat($lettersTotal, "º is ", $letter, ",")替换外部return子句。对于单个结果字符串,将完整的表达式包装在 string-join(, " ") 中。这会让你得到你想要的。
  • 感谢您对我的错误解释感到抱歉,但有没有办法从循环内部做到这一点。就像我想每次从最后一个循环打印它一样:1a,1a 2b,1a 2b 3c ... 例如
  • 不,没有这个功能。
【解决方案2】:

新问题 - 新答案。

但是原理还是一样的:先产生一个未编号的结果,然后再应用编号。这可能需要重写结果。

插入您的代码,而不是下面的 XML 注释。

declare function local:renumber($number, $string)
{
  replace($string, 'THIS IS WHAT IM LOOKING', string($number))
};

declare function local:renumber($subSubElems, $number, $nodes)
{
  for $node in $nodes
  return
    typeswitch ($node)
    case attribute()              return attribute {node-name($node)} {local:renumber($number, $node)}
    case processing-instruction() return processing-instruction {name($node)} {local:renumber($number, $node)}
    case comment()                return comment {local:renumber($number, $node)}
    case text()                   return text {local:renumber($number, $node)}
    default (: element() :) return
      element {node-name($node)}
      {
        local:renumber
        (
          $subSubElems, 
          if ($subSubElems[. is $node]) then count($subSubElems[. << $node]) + 1 else $number, 
          ($node/@*, $node/node())
        )
      }
};

let $result := <result>{<!-- your code here -->}</result>
return local:renumber($result//SubSubElem, 0, $result/node())

【讨论】:

  • 哇,作为替代解决方案,它可以很好地工作。谢谢!!只要没有更好的更简单的计数器选项,我就会使用它!
猜你喜欢
  • 2023-03-15
  • 2018-12-25
  • 2019-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-10
  • 1970-01-01
相关资源
最近更新 更多