MarkLogic TDE XPATH无法重复组

时间:2017-05-21 12:34:44

标签: xml xpath marklogic

我正在使用ML版本9.0并开始使用TDE(模板驱动提取)。我有很多XML文件(3500 xml文件,每个50 kb)并成功加载到ML。我创建了一些成功的基本模板(TDE)。但是当我到达同一元素组的重复组时,视图返回一个空结果。唯一的方法是将上下文设置在一个我不想要的较低级别,因为我无法从更高的节点中选择元素。

下面的XML定义显示了XML文件的示例:

<scope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <item>
        <transaction>
            <type>CI</type>
            <sscc>00000379471900000025</sscc>
            <location>4260210630688</location>
            <device>VISTALINK.004</device>
            <date>2017-04-25</date>
            <time>02:15:33</time>
            <gmtOffset>+02:00</gmtOffset>
            <actorId>155081</actorId>
        </transaction>
        <order>
            <orderNumber>3794719</orderNumber>
        </order>
        <load>
            <rti>
                <ean>8714548186004</ean>
                <grai>8003087145481860040019877322</grai>
                <column>2</column>
                <size>
                    <width>1900</width>
                    <height>95</height>
                    <depth>0</depth>
                </size>
                <position>
                    <x>2062,48707520218</x>
                    <y>2015,24337520512</y>
                    <z>0</z>
                </position>
            </rti>
            <rti>
                <ean>8714548106002</ean>
                <grai>8003087145481060020016434653</grai>
                <column>0</column>
                <size>
                    <width>1900</width>
                    <height>95</height>
                    <depth>0</depth>
                </size>
                <position/>
            </rti>
            <rti>
                <ean>8714548186004</ean>
                <grai>8003087145481860040012803719</grai>
                <column>2</column>
                <size>
                    <width>1900</width>
                    <height>95</height>
                    <depth>0</depth>
                </size>
                <position>
                    <x>2064,20629390666</x>
                    <y>2124,57539157396</y>
                    <z>0</z>
                </position>
            </rti>
            <rti>...</rti>
            <rti>...</rti>
            <rti>...</rti>
            <rti>...</rti>
            <rti>...</rti>
        </load>
    </item>
</scope>

我已经可以通过应用以下模板从/scope/item/transaction/type/scope/item/order/orderNumber中进行选择:

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</context>
  <rows>
    <row>
      <schema-name>main</schema-name>
      <view-name>transactions</view-name>
      <columns>
        <column>
          <name>type</name>
          <scalar-type>string</scalar-type>
          <val>transaction/type</val>
        </column>
        <column>
          <name>Ordernumber</name>
          <scalar-type>long</scalar-type>
          <val>order/orderNumber</val>
        </column>
    </columns>
    </row>
  </rows>
</template>
return tde:template-insert("Transactions.xml", $transactions)

但是当我基于相同的结构创建一个新模板时,选择另一个级别的元素(/scope/item/load),它返回一个空视图。

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

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

正如我之前提到的,我不想更改上下文,因为我无法选择ordertransaction个节点。

我还尝试在1 xml文档上使用xpath和xquery来获取元素。这很好用。

xquery version "1.0-ml";
declare namespace html = "http://www.w3.org/1999/xhtml";

fn:doc('/transaction/2017-04-25_02-15-33_3794719_00000379471900000025_CI.xml')/scope/item/load/rti/grai/text()

2 个答案:

答案 0 :(得分:4)

要从单个文档生成多行,模板的上下文必须与重复子结构中的元素(或JSON属性)匹配。

在这种情况下,模板可能与rti匹配。

模板的值表达式可以具有向上相对路径,因此您可以使用包含重复详细子结构的主结构中的值生成详细信息中的列。

您可以使用该功能在相关主行的详细信息行中插入外键(或将主数据反规范化为详细信息行)。

在这种情况下,模板可能会为订单号添加外键列。

这不是限制性的,因为模板文档可以包含多个模板,这些模板将行投影到文档不同部分的不同视图中。

在这种情况下,容器模板可以使用范围作为上下文,并使用每个文档一行填充订单范围视图,而包含的模板使用rti作为上下文,并使用每个文档多行填充项目rti视图,通过对作用域行的主键的外键将每个rti行与作用域行相关联。

希望有帮助,

答案 1 :(得分:1)

除了Erik的好答案之外,我还想说明他对将item/transactionitem/order值非规范化为item/load/rti&#39;行的评论。第

使用以下代码将示例文档加载到数据库中:

xdmp:document-insert("/nesting-tde-test.xml",
<scope>
    <item>
        <transaction>
            <type>CI</type>
            <sscc>00000379471900000025</sscc>
            <location>4260210630688</location>
            <device>VISTALINK.004</device>
            <date>2017-04-25</date>
            <time>02:15:33</time>
            <gmtOffset>+02:00</gmtOffset>
            <actorId>155081</actorId>
        </transaction>
        <order>
            <orderNumber>3794719</orderNumber>
        </order>
        <load>
            <rti>
                <ean>8714548186004</ean>
                <grai>8003087145481860040019877322</grai>
                <column>2</column>
                <size>
                    <width>1900</width>
                    <height>95</height>
                    <depth>0</depth>
                </size>
                <position>
                    <x>2062,48707520218</x>
                    <y>2015,24337520512</y>
                    <z>0</z>
                </position>
            </rti>
            <rti>
                <ean>8714548106002</ean>
                <grai>8003087145481060020016434653</grai>
                <column>0</column>
                <size>
                    <width>1900</width>
                    <height>95</height>
                    <depth>0</depth>
                </size>
                <position></position>
            </rti>
            <rti>
                <ean>8714548186004</ean>
                <grai>8003087145481860040012803719</grai>
                <column>2</column>
                <size>
                    <width>1900</width>
                    <height>95</height>
                    <depth>0</depth>
                </size>
                <position>
                    <x>2064,20629390666</x>
                    <y>2124,57539157396</y>
                    <z>0</z>
                </position>
            </rti>
        </load>
    </item>
</scope>)

如果您尝试使用item作为上下文运行TDE模板,它将失败:

import module namespace tde = "http://marklogic.com/xdmp/tde" at "/MarkLogic/tde.xqy";

let $doc := doc("/nesting-tde-test.xml")
let $template :=
<template xmlns="http://marklogic.com/xdmp/tde">
  <context>item</context>
  <rows>
    <row>
      <schema-name>main</schema-name>
      <view-name>transactions</view-name>
      <columns>
        <column>
          <name>type</name>
          <scalar-type>string</scalar-type>
          <val>transaction/type</val>
        </column>
        <column>
          <name>Ordernumber</name>
          <scalar-type>long</scalar-type>
          <val>order/orderNumber</val>
        </column>
        <column>
          <name>rti</name>
          <scalar-type>string</scalar-type>
          <val>load/rti/grai</val>
        </column>
    </columns>
    </row>
  </rows>
</template>
let $_ := tde:validate($template)
return try {
  tde:node-data-extract($doc, $template)
} catch ($e) {
  $e/error:format-string/data()
}

以上回报:

  

列的评估rti =&#39; load / rti / grai&#39;返回多个节点(只有一个节点)

然而,您可以更改上下文以使用item/load/rti,然后使用parent::ancestor::轴或父缩写..访问祖先:

import module namespace tde = "http://marklogic.com/xdmp/tde" at "/MarkLogic/tde.xqy";

let $doc := doc("/nesting-tde-test.xml")
let $template :=
<template xmlns="http://marklogic.com/xdmp/tde">
  <context>item/load/rti</context>
  <rows>
    <row>
      <schema-name>main</schema-name>
      <view-name>transactions</view-name>
      <columns>
        <column>
          <name>type</name>
          <scalar-type>string</scalar-type>
          <val>../../transaction/type</val>
        </column>
        <column>
          <name>Ordernumber</name>
          <scalar-type>long</scalar-type>
          <val>../../order/orderNumber</val>
        </column>
        <column>
          <name>rti</name>
          <scalar-type>string</scalar-type>
          <val>grai</val>
        </column>
    </columns>
    </row>
  </rows>
</template>
let $_ := tde:validate($template)
return tde:node-data-extract($doc, $template)

后者返回:

{
    "/nesting-tde-test.xml": [{
        "row": {
            "schema": "main",
            "view": "transactions",
            "data": {
                "rownum": "1",
                "type": "CI",
                "Ordernumber": 3794719,
                "rti": "8003087145481860040019877322"
            }
        }
    }, {
        "row": {
            "schema": "main",
            "view": "transactions",
            "data": {
                "rownum": "2",
                "type": "CI",
                "Ordernumber": 3794719,
                "rti": "8003087145481060020016434653"
            }
        }
    }, {
        "row": {
            "schema": "main",
            "view": "transactions",
            "data": {
                "rownum": "3",
                "type": "CI",
                "Ordernumber": 3794719,
                "rti": "8003087145481860040012803719"
            }
        }
    }]
}

HTH!