MarkLogic TDE XPATH 不适用于重复组
MarkLogic TDE XPATH not working on repeating group
我正在使用 ML 9.0 版并开始使用 TDE(模板驱动提取)。我有很多 XML 个文件(3500 个 xml 个文件,每个文件 50 kb)并将它们成功加载到 ML。我成功创建了一些基本模板 (TDE)。但是当我到达同一元素组的重复组时,视图 returns 为空结果。唯一的方法是将上下文设置在我不想要的较低级别,因为我无法 select 元素形成更高的节点。
下面的 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
select:
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)
但是,当我基于相同结构创建新模板时,select使用另一层元素 (/scope/item/load
) 它 returns 是一个空视图。
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)
正如我之前提到的,我不想更改上下文,因为我无法 select order
或 transaction
节点。
我还尝试在 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()
要从单个文档生成多行,模板的上下文必须匹配重复子结构中的元素(或 JSON 属性)。
在这种情况下,模板很可能匹配 rti。
模板的值表达式可以具有向上的相对路径,因此您可以使用包含重复详细信息子结构的主结构中的值在详细信息中生成列。
您可以使用该功能在相关主行的详细信息行中插入外键(或将主数据非规范化为详细信息行)。
在这种情况下,模板可能会为订单号添加一个外键列。
这不是限制性的,因为模板文档可以包含多个模板,这些模板将行从文档的不同部分投影到不同的视图中。
在这种情况下,容器模板可能使用范围作为上下文,并使用每个文档一行填充订单范围视图,而包含的模板使用 rti 作为上下文,并使用每个文档的多行填充项目 rti 视图文档,通过范围行的主键的外键将每个 rti 行与范围行相关联。
希望对您有所帮助,
除了 Erik 的好回答之外,我还想说明他关于将 item/transaction
和 item/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()
}
以上returns:
Eval for Column rti='load/rti/grai' returns multiple nodes (only one is expected)
然而,您可以更改上下文以使用 item/load/rti
,然后使用 parent::
或 ancestor::
轴或父缩写 ..
:[=23= 访问祖先]
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)
后者returns:
{
"/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!
我正在使用 ML 9.0 版并开始使用 TDE(模板驱动提取)。我有很多 XML 个文件(3500 个 xml 个文件,每个文件 50 kb)并将它们成功加载到 ML。我成功创建了一些基本模板 (TDE)。但是当我到达同一元素组的重复组时,视图 returns 为空结果。唯一的方法是将上下文设置在我不想要的较低级别,因为我无法 select 元素形成更高的节点。
下面的 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
select:
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)
但是,当我基于相同结构创建新模板时,select使用另一层元素 (/scope/item/load
) 它 returns 是一个空视图。
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)
正如我之前提到的,我不想更改上下文,因为我无法 select order
或 transaction
节点。
我还尝试在 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()
要从单个文档生成多行,模板的上下文必须匹配重复子结构中的元素(或 JSON 属性)。
在这种情况下,模板很可能匹配 rti。
模板的值表达式可以具有向上的相对路径,因此您可以使用包含重复详细信息子结构的主结构中的值在详细信息中生成列。
您可以使用该功能在相关主行的详细信息行中插入外键(或将主数据非规范化为详细信息行)。
在这种情况下,模板可能会为订单号添加一个外键列。
这不是限制性的,因为模板文档可以包含多个模板,这些模板将行从文档的不同部分投影到不同的视图中。
在这种情况下,容器模板可能使用范围作为上下文,并使用每个文档一行填充订单范围视图,而包含的模板使用 rti 作为上下文,并使用每个文档的多行填充项目 rti 视图文档,通过范围行的主键的外键将每个 rti 行与范围行相关联。
希望对您有所帮助,
除了 Erik 的好回答之外,我还想说明他关于将 item/transaction
和 item/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()
}
以上returns:
Eval for Column rti='load/rti/grai' returns multiple nodes (only one is expected)
然而,您可以更改上下文以使用 item/load/rti
,然后使用 parent::
或 ancestor::
轴或父缩写 ..
:[=23= 访问祖先]
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)
后者returns:
{
"/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!