1

Hello i am using MarkLogic 9.0 and have a beginner level of experience with ML and XML. I have followed the MarkLogic SQL Guide successfully and want to use it in the real world and extract from transactional xml files the the type element. But in the view which i created returns an empty result. I think it has something to do with the xsd and the xsi. But as I mentioned earlier I am at a beginner level and I don't know how to fix this.

The following text describe the scenario to reproduce the problem.

I load 3500 xml documents to the SQLData(with triple store index) I also created a SQLSchema database which is related tot the SQLData database as described in the Guide. All XML documents has a similar structure like the example below:

<?xml  version="1.0" encoding="UTF-8"?>
<scope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <item>
    <transaction>
      <type>CI</type>
      <sscc>00000379461100000007</sscc>
      <location>4260210630688</location>
      <device>VISTALINK.004</device>
      <date>2017-04-25</date>
      <time>01:22:20</time>
      <gmtOffset>+02:00</gmtOffset>
      <actorId>155081</actorId>
    </transaction>
    <order>
      <orderNumber>3794611</orderNumber>
    </order>
  </item>
</scope>

with a URI like this(all documents has a similar structure):

/transactions/2017-04-25_01-22-20_3794611_00000379461100000007_CI.xml

Now i created a template with the following structure:

xquery version "1.0-ml";
import module namespace tde = "http://marklogic.com/xdmp/tde" 
        at "/MarkLogic/tde.xqy";

let $transactions :=
<template xmlns="http://marklogic.com/xdmp/tde">
  <context>/transactions</context>
  <rows>
    <row>
      <schema-name>main</schema-name>
      <view-name>transactions</view-name>
      <columns>
        <column>
          <name>type</name>
          <scalar-type>string</scalar-type>
          <val>type</val>
        </column>
    </columns>
    </row>
  </rows>
</template>
return tde:template-insert("Transactions.xml", $transactions)

I also to change the context to:

<context>item</context>

and /item

It does not return any error so i think the result will be fine

When I execute the following statement in the SQL console it returns an empty result:

select * from transactions;

When I validate the above template it returns the folowing result:

<map:map xmlns:map="http://marklogic.com/xdmp/map" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<map:entry key="valid">
<map:value xsi:type="xs:boolean">false</map:value>
</map:entry>
<map:entry key="error">
<map:value xsi:type="xs:string">TDE-INVALIDTEMPLATENODE</map:value>
</map:entry>
<map:entry key="message">
<map:value xsi:type="xs:string">TDE-INVALIDTEMPLATENODE: Invalid extraction template node: /tde:template/tde:rows/text()</map:value>
</map:entry>
</map:map>

So the error by validating is :

Invalid extraction template node: /tde:template/tde:rows/text()
Invalid extraction template node: 

/tde:template/tde:rows/text()

Does any one know how I can fix this?

Mads Hansen
  • 63,927
  • 12
  • 112
  • 147
Erik hoeven
  • 1,442
  • 6
  • 26
  • 41
  • Maybe it is just a simple mistake. You have `/transactions`, but context is like an XSLT match expression, not a directory filter. You probably want to change the value to `transaction` or `item`, since there is no element with the name `transactions`. – grtjn May 18 '17 at 12:28
  • Thanks for the reply. I try to change the value of the context element to item or transaction both get the same result (see adjust question). – Erik hoeven May 18 '17 at 12:48
  • I adjust now some aditional information about the validating results – Erik hoeven May 18 '17 at 13:34

1 Answers1

4

The problem is in your context. You have specified <context>item</context> but based on your sample document item is a child of scope. Therefore your template should look like this:

xquery version "1.0-ml";
import module namespace tde = "http://marklogic.com/xdmp/tde" at "/MarkLogic/tde.xqy";

let $transactions :=
<template xmlns="http://marklogic.com/xdmp/tde">
  <context>/scope/item/transaction</context>
  <rows>
    <row>
      <schema-name>main</schema-name>
      <view-name>transactions</view-name>
      <columns>
        <column>
          <name>type</name>
          <scalar-type>string</scalar-type>
          <val>type</val>
        </column>
    </columns>
    </row>
  </rows>
</template>
return tde:template-insert("Transactions.xml", $transactions)

So what are we doing here? We are specifying the context to be /scope/item/transaction because the column type that you've specified in your row definition is under these elements. Loading this template will allow you to run the SQL statement SELECT * FROM transactions;

Tamas
  • 10,953
  • 13
  • 47
  • 77
  • 1
    You can leave off `/scope/item/` from the context. It accepts ["Any indexable path expression"](http://docs.marklogic.com/guide/app-dev/TDE#id_71415), but should indeed be `transaction` rather than `item`, otherwise the expression for the `type` column won't return anything, and TDE will complain: `Eval for Column type='type' returns an empty sequence for a non-nullable column`.. – grtjn May 18 '17 at 15:12
  • No worries at all :) – Tamas May 18 '17 at 16:31