1

我有一个返回电话号码的函数。它以这种格式返回

<td>#phone</td>

该函数可以返回任意数量的值。我想以网格状结构显示它们。即其中有 10 列的表。(所以如果函数返回 26 条记录,那么我将有 3 行:两行 10 列,第三行 6 列。)

我无法理解 XQuery 中 for 语句中的计数器逻辑(带有关键字 at 的语句)。任何帮助,将不胜感激。

函数调用是这样的(对函数调用的任何修改也非常感谢):

实际代码是这样的:

declare function local:table-construct(
  $areacode as xs:string, 
  $uniquekey as $xs:string, 
  $doc as xs:element) as xs:element?
{
  for $phno in $doc/users[$areacode eq $code and $uniquekey eq $thiskey]
  return <td>{$phno/phone}</td>
}

let $doc := <an xml doc from a database>
let $areacode := "somestring"
let $uniquekey := "somekey"
return 
  <html>
    <body>
      <table>
        <tr>{local:table-construct($areacode, $uniquekey, $doc)}</tr>
      </table>
    </body>
  </html>

目前的格式为我提供了同一行中的所有电话号码。我希望表格只显示 10 行。以及下一行中的剩余数据。

4

3 回答 3

1

因为您没有提供任何代码,我只能猜测您陷入了“函数式编程”陷阱。XQuery 是一种函数式语言,没有命令式语言中已知的变量,最好将它们视为常量。

let $x := 1 to 10
let $sum := 0
for $i in $x
let $sum := $sum+$i (: here we cover $sum from line 2, do not change it :)
return $sum

此代码的输出1 2 3 4 5 6 7 8 9 10可能是意外的。在第 4 行中,我们总是添加$i(1 到 10) 和$sum(0),但我们不更新$sum而是覆盖它。对于下一个$i$sum将再次为 0。

如果这是问题所在,请考虑使用如下模式:

let $seq := 1 to 15
let $dividor := 4
for $i in 1 to ceiling(count($seq) div $dividor) cast as xs:integer
return <tr>{
  for $td in subsequence($seq, ($i -1)*$dividor + 1, $dividor)
  return <td>{$td}</td>
}</tr>

您可能必须将其适应您的代码,但这个想法应该没问题。

编辑:如果您的查询处理器支持它,您也可以使用滑动窗口。从 5.0.2 版开始,Marklogic 仍然没有。

于 2012-01-06T11:13:41.150 回答
0

也许这会有所帮助,您可以根据您的要求在 xslt 中进行分组!

<xsl:stylesheet version="1.0"   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:variable name="Columns" select="10"/>

  <xsl:template match="/*">
    <xsl:copy>
      <xsl:apply-templates select="phone[position() mod $Columns= 1]"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="phone">
    <tr>
      <xsl:apply-templates mode="copy" select=". | following-sibling::phone[position() &lt; $Columns]"/>
    </tr>
  </xsl:template>

  <xsl:template match="line" mode="copy">
    <td><xsl:copy-of select="."/><td>
  </xsl:template>
</xsl:stylesheet>
于 2012-01-06T10:32:10.277 回答
0

语句的 at 关键字在FLWOR这里对您没有多大帮助。您需要一次取 10 列并将其放入自己的<tr>. 在 MarkLogic 中执行此操作的最直接方法如下:

declare function local:wrap-columns($columns, $width) {
  let $nrrows := ceiling(count($columns) div $width)
  for $row in 1 to $nrrows
  let $start := ($row - 1) * $width + 1
  let $end := $row * $width
  return
    <tr>{$columns[$start to $end]}</tr>
};

let $columns :=
  for $i in 1 to 26
  return <td>{$i}</td>
return
  local:wrap-columns($columns, 10)

乍一看,它类似于 Ranon 的解决方案(老实说,巧合),尽管包装在一个函数中以使集成和重用更容易。

中的解决方案XSLT也可以,但是如果您还没有使用XSLT,那么XQuery我猜想在这里使用更有意义。

于 2012-01-07T12:52:53.467 回答