不同的属性名称
Distinct attribute names
我想使用 XQuery select 产品中每篇文章的特殊值。
我目前拥有的:
输入XML(摘录):
<product type="product" id="2246091">
<product type="article">
<attribute identifier="EXAMPLE1" type="BOOLEAN">0</attribute>
<attribute identifier="EXAMPLE2" type="BOOLEAN">1</attribute>
</product>
<product type="article">
<attribute identifier="EXAMPLE1" type="BOOLEAN">1</attribute>
<attribute identifier="EXAMPLE2" type="BOOLEAN">1</attribute>
</product>
<product type="article">
<attribute identifier="EXAMPLE1" type="BOOLEAN">0</attribute>
<attribute identifier="EXAMPLE2" type="BOOLEAN">1</attribute>
</product>
</product>
XQuery:
for $i in //product
[@type = 'product'
and @id = '2246091']
//attribute
[@type='BOOLEAN'
and @identifier= ('EXAMPLE1', 'EXAMPLE2') ]
where $i = '1'
return $i
这 return 向我发送了 product
下每篇文章的每个 attribute
元素,其中内容为“1”,其标识符为 EXAMPLE1 或 EXAMPLE2。
可能是,第 1 条中有与第 2 条中相同的 attribute
标识符(例如 EXAMPLE1)。
我得到的是:
<?xml version="1.0" encoding="UTF-8"?>
<attribute identifier="EXAMPLE2" type="BOOLEAN">1</attribute>
<attribute identifier="EXAMPLE1" type="BOOLEAN">1</attribute>
<attribute identifier="EXAMPLE2" type="BOOLEAN">1</attribute>
<attribute identifier="EXAMPLE2" type="BOOLEAN">1</attribute>
我试图在我的 for
循环周围添加一个不同的值,但这将 return 我只有 '1'。
我想要的是只获取每个属性一次:
<attribute identifier="EXAMPLE2" type="BOOLEAN">1</attribute>
<attribute identifier="EXAMPLE1" type="BOOLEAN">1</attribute>
听起来好像您想要的是为在内容为 1 的 attribute
元素中找到的 identifier
属性的每个不同值看到一个 attribute
元素。(或者,稍微更具挑战性,每组等效 attribute
元素对应一个 attribute
元素,其中等效由 deep-equals() 定义。)
distinct-values() 函数在这里对您没有帮助,因为它会将任何输入节点强制转换为简单值(此处为 1)。
如果匹配 identifier
属性就足够了
如果 identifier
属性足以在元素之间建立等价关系,那么像下面这样的东西就足够了(未测试):
let $ones := //product[@type = 'product'
and @id = '2246091']
//attribute[@type='BOOLEAN'
and @identifier =
('EXAMPLE1', 'EXAMPLE2') ],
$ids := distinct-values($ones/@identifier)
for $id in $ids
return ($ones[@identifier = $id])[1]
如果需要更一般的等价性检验
如果 @identifier
不足以为您的目的建立等效性,您将不得不做一些更复杂的事情;在一般情况下,一种方法是编写一个包含两个参数的函数(我将其称为 local:equivalent()
),如果这两个参数对于您的目的是等效的,则 returns 为真。然后编写第二个函数来接受一系列项目并从序列中删除重复项(其中 'being a duplicate' 表示“在 local:equivalent()
上返回 true”。像这样的东西可能作为第一近似值(未测试):
(: dedup#1: remove duplicates from a sequence :)
declare function local:dedup(
$items as item()*
) as xs:boolean {
local:dedup($items, ())
};
(: dedup#2: work through the input sequence one
by one, removing duplicates and accumulating
non-duplicates. Cost is n^2 / 2. :)
declare function local:dedup(
$in as item()*,
$out as item()*
) as xs:boolean {
if (empty($in))
then $out
else let $car := head($in)
return if (some $i in $in
satisfies
local:equivalent($i, $car))
then local:dedup(tail($in), $out)
else local:dedup(tail($in), ($car, $out))
};
(: equivalent#2: true iff arguments are equivalent :)
declare function local:equivalent(
$x, $y : item()
) as xs:boolean {
// determine application-specific equivalence
// however you like ...
deep-equal($x, $y)
};
(: Now do the work :)
let $ones := //product[@type = 'product'
and @id = '2246091']
//attribute[@type='BOOLEAN'
and @identifier =
('EXAMPLE1', 'EXAMPLE2') ]
return local:dedup($ones)
那些对高阶函数感到满意的人会想更进一步,通过允许两个 local:dedup
函数接受一个提供等价的附加参数来消除对名为 local:equivalent
的函数的依赖功能。
我想使用 XQuery select 产品中每篇文章的特殊值。
我目前拥有的:
输入XML(摘录):
<product type="product" id="2246091">
<product type="article">
<attribute identifier="EXAMPLE1" type="BOOLEAN">0</attribute>
<attribute identifier="EXAMPLE2" type="BOOLEAN">1</attribute>
</product>
<product type="article">
<attribute identifier="EXAMPLE1" type="BOOLEAN">1</attribute>
<attribute identifier="EXAMPLE2" type="BOOLEAN">1</attribute>
</product>
<product type="article">
<attribute identifier="EXAMPLE1" type="BOOLEAN">0</attribute>
<attribute identifier="EXAMPLE2" type="BOOLEAN">1</attribute>
</product>
</product>
XQuery:
for $i in //product
[@type = 'product'
and @id = '2246091']
//attribute
[@type='BOOLEAN'
and @identifier= ('EXAMPLE1', 'EXAMPLE2') ]
where $i = '1'
return $i
这 return 向我发送了 product
下每篇文章的每个 attribute
元素,其中内容为“1”,其标识符为 EXAMPLE1 或 EXAMPLE2。
可能是,第 1 条中有与第 2 条中相同的 attribute
标识符(例如 EXAMPLE1)。
我得到的是:
<?xml version="1.0" encoding="UTF-8"?>
<attribute identifier="EXAMPLE2" type="BOOLEAN">1</attribute>
<attribute identifier="EXAMPLE1" type="BOOLEAN">1</attribute>
<attribute identifier="EXAMPLE2" type="BOOLEAN">1</attribute>
<attribute identifier="EXAMPLE2" type="BOOLEAN">1</attribute>
我试图在我的 for
循环周围添加一个不同的值,但这将 return 我只有 '1'。
我想要的是只获取每个属性一次:
<attribute identifier="EXAMPLE2" type="BOOLEAN">1</attribute>
<attribute identifier="EXAMPLE1" type="BOOLEAN">1</attribute>
听起来好像您想要的是为在内容为 1 的 attribute
元素中找到的 identifier
属性的每个不同值看到一个 attribute
元素。(或者,稍微更具挑战性,每组等效 attribute
元素对应一个 attribute
元素,其中等效由 deep-equals() 定义。)
distinct-values() 函数在这里对您没有帮助,因为它会将任何输入节点强制转换为简单值(此处为 1)。
如果匹配 identifier
属性就足够了
如果 identifier
属性足以在元素之间建立等价关系,那么像下面这样的东西就足够了(未测试):
let $ones := //product[@type = 'product'
and @id = '2246091']
//attribute[@type='BOOLEAN'
and @identifier =
('EXAMPLE1', 'EXAMPLE2') ],
$ids := distinct-values($ones/@identifier)
for $id in $ids
return ($ones[@identifier = $id])[1]
如果需要更一般的等价性检验
如果 @identifier
不足以为您的目的建立等效性,您将不得不做一些更复杂的事情;在一般情况下,一种方法是编写一个包含两个参数的函数(我将其称为 local:equivalent()
),如果这两个参数对于您的目的是等效的,则 returns 为真。然后编写第二个函数来接受一系列项目并从序列中删除重复项(其中 'being a duplicate' 表示“在 local:equivalent()
上返回 true”。像这样的东西可能作为第一近似值(未测试):
(: dedup#1: remove duplicates from a sequence :)
declare function local:dedup(
$items as item()*
) as xs:boolean {
local:dedup($items, ())
};
(: dedup#2: work through the input sequence one
by one, removing duplicates and accumulating
non-duplicates. Cost is n^2 / 2. :)
declare function local:dedup(
$in as item()*,
$out as item()*
) as xs:boolean {
if (empty($in))
then $out
else let $car := head($in)
return if (some $i in $in
satisfies
local:equivalent($i, $car))
then local:dedup(tail($in), $out)
else local:dedup(tail($in), ($car, $out))
};
(: equivalent#2: true iff arguments are equivalent :)
declare function local:equivalent(
$x, $y : item()
) as xs:boolean {
// determine application-specific equivalence
// however you like ...
deep-equal($x, $y)
};
(: Now do the work :)
let $ones := //product[@type = 'product'
and @id = '2246091']
//attribute[@type='BOOLEAN'
and @identifier =
('EXAMPLE1', 'EXAMPLE2') ]
return local:dedup($ones)
那些对高阶函数感到满意的人会想更进一步,通过允许两个 local:dedup
函数接受一个提供等价的附加参数来消除对名为 local:equivalent
的函数的依赖功能。