没有看到json的预期输出:transform-from-json和fn:tokenize

时间:2014-08-28 12:31:36

标签: marklogic

我们有两个REST扩展。两者都期望来自客户的CSV数据。我们通过json传入完全相同的数据。进入的消息是相同的,我们在服务器上执行收到的json消息的xdmp:log($input),相同:

2014-08-28 12:06:13.443 Info: STRLF3: START VERTALER ++++++++++++++++++++++++++++++++++++
2014-08-28 12:06:13.443 Info: STRLF3: {"ID":"","DingenID":"","VertaalType":"VAN6NAARWIJK","Name":"Vertaling-28-Aug-2014 12:08.txt","Text":"PC,Verkoopprijs\n1000AK,89.99\n1000EA,49.99\n1001GM,100\n1001LA,34.99\n1001MJ,24.99\n1011AC,19.98\n1011AC,20.99\n1011AC,9.98\n1011AC,30.98\n1011BT,999.01\n1011CD,30\n1011DJ,12\n1011DJ,100.98\n1011DJ,99.98\n1011DJ,24.99\n1011DK,18.98\n1011EG,28.98\n1011EK,93.97\n1011EK,50.99\n1011ET,51.49\n1011EZ,51.99\n1011GA,24.99\n1011GD,34.99\n1011GR,35.99\n1011GW,29.99\n1011GW,24.99\n1011HB,14.98\n1011HB,29.99\n1011HB,65.45\n1011HB,28.79\n1011HL,49.99\n1011JH,18.98\n1011JH,19.99\n1011JH,14.98\n1011JX,70\n1011KC,54.98\n1011KK,100\n1011KX,43.98\n1011LE,119\n1011LL,49.99\n1011LL,4.99\n1011LM,64.99\n1011LM,39.95\n1011LS,13.97\n1011LX,20\n1011LZ,29.99\n1011LZ,16.99\n1011MG,49.99\n1011MH,100\n1011MH,79.99\n1011MH,72\n1011MK,31.99\n1011ML,48.98\n1011ML,24.99\n1011ML,83.97\n1011MN,23.98\n1011MN,35.97\n1011MR,30.99\n1011NA,19.8\n1011NC,24.99\n1011NK,73.98\n1011NV,12\n1011NV,19.99\n1011NV,19.99\n1011NV,9.98\n1011NV,4.99\n1011NV,12\n1011PG,50\n1011PG,39.98\n1011PG,24.99\n1011PL,35\n1011PL,366.01\n1011RH,23.99\n1011SG,8.98\n1011SG,10\n1011SP,50.99\n1011SZ,73.98\n1011TB,59.99\n1011TB,49.99\n1011TE,253.01\n1011TE,23.88\n1011TE,9.08\n1011TL,28\n1011TL,9.98\n1011TR,14.99\n1011TR,14.98\n1011TR,13.98\n1011TZ,33.97\n1011VB,220\n1011VZ,38.97\n1011WD,13.97\n1012AC,66.97\n1012AE,15.98\n1012AL,43.98\n1012AL,50.99\n1012BA,19.99\n1012BE,59.99\n1012BJ,29.99\n1012BJ,33.99"}

来自API2呼叫的日志消息:

2014-08-28 12:07:42.264 Info: STRLF3: ++++++++++++++++++ START TRANSACTIONS ++++++++++++++++++++++++++++++++++++
2014-08-28 12:07:42.264 Info: STRLF3: {"ID":"","DingenID":"","ProjectID":268393,"Name":"Transactiedata-28-Aug-2014 12:08.txt","Text":"PC,Verkoopprijs\n1000AK,89.99\n1000EA,49.99\n1001GM,100\n1001LA,34.99\n1001MJ,24.99\n1011AC,19.98\n1011AC,20.99\n1011AC,9.98\n1011AC,30.98\n1011BT,999.01\n1011CD,30\n1011DJ,12\n1011DJ,100.98\n1011DJ,99.98\n1011DJ,24.99\n1011DK,18.98\n1011EG,28.98\n1011EK,93.97\n1011EK,50.99\n1011ET,51.49\n1011EZ,51.99\n1011GA,24.99\n1011GD,34.99\n1011GR,35.99\n1011GW,29.99\n1011GW,24.99\n1011HB,14.98\n1011HB,29.99\n1011HB,65.45\n1011HB,28.79\n1011HL,49.99\n1011JH,18.98\n1011JH,19.99\n1011JH,14.98\n1011JX,70\n1011KC,54.98\n1011KK,100\n1011KX,43.98\n1011LE,119\n1011LL,49.99\n1011LL,4.99\n1011LM,64.99\n1011LM,39.95\n1011LS,13.97\n1011LX,20\n1011LZ,29.99\n1011LZ,16.99\n1011MG,49.99\n1011MH,100\n1011MH,79.99\n1011MH,72\n1011MK,31.99\n1011ML,48.98\n1011ML,24.99\n1011ML,83.97\n1011MN,23.98\n1011MN,35.97\n1011MR,30.99\n1011NA,19.8\n1011NC,24.99\n1011NK,73.98\n1011NV,12\n1011NV,19.99\n1011NV,19.99\n1011NV,9.98\n1011NV,4.99\n1011NV,12\n1011PG,50\n1011PG,39.98\n1011PG,24.99\n1011PL,35\n1011PL,366.01\n1011RH,23.99\n1011SG,8.98\n1011SG,10\n1011SP,50.99\n1011SZ,73.98\n1011TB,59.99\n1011TB,49.99\n1011TE,253.01\n1011TE,23.88\n1011TE,9.08\n1011TL,28\n1011TL,9.98\n1011TR,14.99\n1011TR,14.98\n1011TR,13.98\n1011TZ,33.97\n1011VB,220\n1011VZ,38.97\n1011WD,13.97\n1012AC,66.97\n1012AE,15.98\n1012AL,43.98\n1012AL,50.99\n1012BA,19.99\n1012BE,59.99\n1012BJ,29.99\n1012BJ,33.99"}

然后我们进入代码的这一部分:

在API 1中,我们有:

        let $_ := xdmp:log("START VERTALER ++++++++++++++++++++++++++++++++++++")
        let $_ := xdmp:log($input)

        let $id         := sl3:get-id("/app/vertaler/", "json")
        let $uri        := fn:concat("/app/vertaler/", $id, ".xml")
        let $xml        := json:transform-from-json($input)
        let $vertaaltype:= $xml//jbasic:VertaalType/text()
        let $fileID     := $xml//jbasic:ID/text()
              let $preurl     := 'http://streetlife.dikw.com'

        (: do vertaal magic here ... :)
        let $text := $xml//jbasic:Text/text()

        let $_ := xdmp:log(fn:concat("Recieved text data, raw: ", $input))
        let $codes := fn:tokenize($text,'\n')
        (: check if tokenization is ok :)
        let $_ := xdmp:log(fn:concat("Recieved text data, count: ", fn:count($codes)))

结果API1:

2014-08-28 12:06:13.445 Info: STRLF3: Recieved text data, count: 100

我们看到文件已正确解析。

在API 2中,我们有:

    let $project  := json:transform-from-json($input)/ns:ProjectID
    let $codes    := json:transform-from-json($input)/ns:Text
    let $_ := xdmp:log(fn:concat("123 Recieved text data, raw: ", $input))

    let $text     := fn:tokenize($codes,'
') (: 
 of '/n'  :)
    let $_ := xdmp:log(fn:concat("Recieved text data, count: ", fn:count($text)))

结果API 2,\n作为标记字符:

2014-08-28 12:07:42.266 Info: STRLF3: Recieved text data, count: 1

API 1需要fn:tokenize($ text,' \ n')和API2需要fn:tokenize($ codes,'
')。额外的空间是有意的。

json:transform-from-json的预期结果是什么? API 1或2的行为,或换句话说我需要使用\n
进行标记?正如您所看到的,我有两个api,每个都在工作,但没有使用tokenize函数中的另一个值......

让我感到困惑的是,我检查了行的行,包括命名空间和模块的加载,但我仍然无法找到差异。

3 个答案:

答案 0 :(得分:1)

如果在调用json:transform-from-json()时未提供配置,则结果为“http://marklogic.com/xdmp/json/basic”命名空间中的XML。

第一个示例将jsbasic前缀绑定到该命名空间,并使用后代XPath(“//”)来提取属性。

假设第二个示例将ns前缀绑定到... / json / basic命名空间,XPath会尝试匹配根目录下的属性。由没有配置的transform-to-json生成的XML中的根始终是“json”(带有命名空间),因此XPath将不匹配。根据JSON的结构,可能会使用后代XPath(“//”),如第一个示例所示。

在第二个示例中,您可能还想从变量中捕获json:transform-from-json()中的输出以提高效率,如:

let $xml      := json:transform-from-json($input)
let $project  := $xml//ns:ProjectID
let $codes    := $xml//ns:Text

如果这不起作用,请尝试记录$ xml以检查转换的输出。

这是文档:

答案 1 :(得分:0)

我怀疑换行线是一个问题。

xdmp:to-json(
  'line 1
line 2')

=> "line 1\nline 2"

现在尝试添加tokenize

xdmp:to-json(
  'line 1
line 2')
! tokenize(., '\n')

=> "line 1\nline 2"

那不会做任何事情,因为tokenize将其第二个参数视为正则表达式。因此,正则表达式\n匹配文字换行符,而输入中的换行符实际上是两个字符\n

xdmp:to-json(
  'line 1
line 2')
! tokenize(., '\\n')

=> "line 1
line 2"

这更接近我们想要的东西。我可能也不想要输出中的双引号字符。但这只是为了说明换行符可能是什么问题。

答案 2 :(得分:0)

我仍然不明白问题是什么,但这适用于7.0-3:

let $input := '{"ID":"","DingenID":"","ProjectID":268393,"Name":"Transactiedata-28-Aug-2014 12:08.txt","Text":"PC,Verkoopprijs\n1000AK,89.99\n1000EA,49.99\n1001GM,100\n1001LA,34.99\n1001MJ,24.99\n1011AC,19.98\n1011AC,20.99\n1011AC,9.98\n1011AC,30.98\n1011BT,999.01\n1011CD,30\n1011DJ,12\n1011DJ,100.98\n1011DJ,99.98\n1011DJ,24.99\n1011DK,18.98\n1011EG,28.98\n1011EK,93.97\n1011EK,50.99\n1011ET,51.49\n1011EZ,51.99\n1011GA,24.99\n1011GD,34.99\n1011GR,35.99\n1011GW,29.99\n1011GW,24.99\n1011HB,14.98\n1011HB,29.99\n1011HB,65.45\n1011HB,28.79\n1011HL,49.99\n1011JH,18.98\n1011JH,19.99\n1011JH,14.98\n1011JX,70\n1011KC,54.98\n1011KK,100\n1011KX,43.98\n1011LE,119\n1011LL,49.99\n1011LL,4.99\n1011LM,64.99\n1011LM,39.95\n1011LS,13.97\n1011LX,20\n1011LZ,29.99\n1011LZ,16.99\n1011MG,49.99\n1011MH,100\n1011MH,79.99\n1011MH,72\n1011MK,31.99\n1011ML,48.98\n1011ML,24.99\n1011ML,83.97\n1011MN,23.98\n1011MN,35.97\n1011MR,30.99\n1011NA,19.8\n1011NC,24.99\n1011NK,73.98\n1011NV,12\n1011NV,19.99\n1011NV,19.99\n1011NV,9.98\n1011NV,4.99\n1011NV,12\n1011PG,50\n1011PG,39.98\n1011PG,24.99\n1011PL,35\n1011PL,366.01\n1011RH,23.99\n1011SG,8.98\n1011SG,10\n1011SP,50.99\n1011SZ,73.98\n1011TB,59.99\n1011TB,49.99\n1011TE,253.01\n1011TE,23.88\n1011TE,9.08\n1011TL,28\n1011TL,9.98\n1011TR,14.99\n1011TR,14.98\n1011TR,13.98\n1011TZ,33.97\n1011VB,220\n1011VZ,38.97\n1011WD,13.97\n1012AC,66.97\n1012AE,15.98\n1012AL,43.98\n1012AL,50.99\n1012BA,19.99\n1012BE,59.99\n1012BJ,29.99\n1012BJ,33.99"}'
let $m := xdmp:from-json($input)
let $text as xs:string := map:get($m, 'Text')
let $records := tokenize($text, '\n')
let $labels := tokenize($records[1], ',')
let $data := subsequence($records, 2)
for $i in $data
let $seq := tokenize($i, ',')
return text { $labels[1], $seq[1], $labels[2], $seq[2] }

我使用xdmp:from-json来解析JSON,而不是json:transform-from-json。我不确定这是否与换行处理有任何不同,但它返回一个json字典对象。这就像一张地图:地图项,除了按键排序。

无论如何,这会返回:

PC 1000AK Verkoopprijs 89.99
PC 1000EA Verkoopprijs 49.99
PC 1001GM Verkoopprijs 100
PC 1001LA Verkoopprijs 34.99
...

您也可以使用json:transform-from-json执行此操作。将$m$text的分配替换为:

let $text as xs:string := json:transform-from-json($input)/xjb:Text


上的标记对我来说同样适用于任何代码示例。