【问题标题】:MarkLogic TDE XPATH not working on repeating groupMarkLogic TDE XPATH 不适用于重复组
【发布时间】:2017-05-21 12:34:44
【问题描述】:

我正在使用 ML 9.0 版并开始使用 TDE(模板驱动提取)。我有很多 XML 文件(3500 个 50 kb 的 xml 文件)并将它们成功加载到 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()

【问题讨论】:

    标签: xml xpath marklogic


    【解决方案1】:

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

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

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

    您可以使用该功能在相关主行的明细行中插入外键(或将主数据非规范化到明细行中)。

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

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

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

    希望对您有所帮助,

    【讨论】:

    • 感谢 ehenum 帮助解释。我理解正确!您说 RTI 视图的上下文必须设置为:“/scope/item/load/rti”,我可以使用外键引用包含主键的父视图?
    • 我对模型的理解是orderNumber是scope的主键(主行)。如果正确,则 rti 详细信息行的模板可以生成以 orderNumber 作为外键的列。然后,在查询时,范围行可以在适当的时候与 rti 行连接。另一种方法是将所有范围主值作为每个 rti 详细信息行中的列发出(即,在索引中非规范化而不是在查询中加入)。
    【解决方案2】:

    除了 Erik 的好答案之外,我想说明他关于将 item/transactionitem/order 值非规范化为 item/load/rti 的行的评论。

    将示例文档加载到数据库中:

    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()
    }
    

    以上返回:

    Eval for Column rti='load/rti/grai' 返回多个节点(预计只有一个)

    但是,您可以更改上下文以使用 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!

    【讨论】:

    • 感谢您的快速回复,我现在和家人一起度假。所以我希望你接受延迟提交和测试答案!
    猜你喜欢
    • 2021-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-09
    • 1970-01-01
    • 2013-07-02
    • 2021-07-06
    • 1970-01-01
    相关资源
    最近更新 更多