如何合并元素并将它们分组
How to merge elements and group them
如何合并以下 XML 片段:
片段 1:
<drug>
<title>Paracetamol</title>
<indications outputclass="indicationsAndDose">
<title>Indications and dose</title>
<body>
<section outputclass="indicationAndDoseGroup">
<sectiondiv outputclass="therapeuticIndications">
<p outputclass="therapeuticIndication">Some indication 1</p>
<p outputclass="therapeuticIndication">Some indication 2</p>
</sectiondiv>
</section>
</body>
</indications>
</drug>
片段 2:
<drug>
<title>Abacavir</title>
<indications outputclass="indicationsAndDose">
<title>Indications and dose</title>
<body>
<section outputclass="indicationAndDoseGroup">
<sectiondiv outputclass="therapeuticIndications">
<p outputclass="therapeuticIndication">Some indication 2</p>
</sectiondiv>
</section>
</body>
</indications>
</drug>
接受标准:
我需要输出一个 XML 片段,它是片段 1 和片段 2 的超集,但需要根据元素、属性和值以不同的方式完成。
- 当元素相同但值不同并且它们没有属性时,它们应该被合并,例如"Paracetamol" 和 "Abacavir"
- 当元素具有相同的属性时,它们应该是合并值,例如"Some indication 1"
解决方案应该是动态的,因为上述规则可以应用于任何类型的元素,即 <title>
<section>
<p>
等
<drug>
<title>Paracetamol</title>
<indications outputclass="indicationsAndDose">
<title>Indications and dose</title>
<body>
<section outputclass="indicationAndDoseGroup">
<sectiondiv outputclass="therapeuticIndications">
<p outputclass="therapeuticIndication">Some indication 1</p>
<p outputclass="therapeuticIndication">Some indication 2</p>
</sectiondiv>
</section>
</body>
</indications>
</drug>
我不确定这是否是您想要的那种合并,因为您的要求很模糊!但是,它会根据您提供的输入生成输出:
declare variable $local:xml1 := document {
<drug>
<title>Paracetamol</title>
<indications outputclass="indicationsAndDose">
<title>Indications and dose</title>
<body>
<section outputclass="indicationAndDoseGroup">
<sectiondiv outputclass="therapeuticIndications">
<p outputclass="therapeuticIndication">Some indication 1</p>
</sectiondiv>
</section>
</body>
</indications>
</drug>
};
declare variable $local:xml2 := document {
<drug>
<title>Abacavir</title>
<indications outputclass="indicationsAndDose">
<title>Indications and dose</title>
<body>
<section outputclass="indicationAndDoseGroup">
<sectiondiv outputclass="therapeuticIndications">
<p outputclass="therapeuticIndication">Some indication 2</p>
</sectiondiv>
</section>
</body>
</indications>
</drug>
};
declare function local:merge($i1, $i2) {
if (node-name($i1) eq node-name($i2)) then
(
(: When elements are the same and the value is different
and they have no attributes they should be merged
e.g. "Paracetamol" and "Abacavir"
:)
if (empty(($i1/@*, $i2/@*))) then
element {node-name($i1)} {
$i1/@*,
$i1/text(),
let $ii1 := $i1/node()[1]
let $ii2 := $i2/node()[1]
return
if (not(empty($ii1)) and not(empty($ii2))) then
local:merge($ii1, $ii2)
else()
}
(: When the elements have the same attribute then they
should be merged value e.g. "Some indication 1"
:)
else if (fn:deep-equal($i1/@*, $i2/@*)) then
(
element {node-name($i1)} {
$i1/@*,
$i1/text(),
let $ii1 := $i1/node()[1]
let $ii2 := $i2/node()[1]
return
if (not(empty($ii1)) and not(empty($ii2))) then
local:merge($ii1, $ii2)
else()
},
if (not(empty($i1/text())) and not(empty($i2/text()))) then
element {node-name($i2)} {
$i2/@*,
$i2/text()
}
else()
)
else (),
let $ii1 := $i1/following-sibling::node()[1]
let $ii2 := $i2/following-sibling::node()[1]
return
if (not(empty($ii1)) and not(empty($ii2))) then
local:merge($ii1, $ii2)
else()
)
else()
};
local:merge($local:xml1/drug, $local:xml2/drug)
如何合并以下 XML 片段:
片段 1:
<drug>
<title>Paracetamol</title>
<indications outputclass="indicationsAndDose">
<title>Indications and dose</title>
<body>
<section outputclass="indicationAndDoseGroup">
<sectiondiv outputclass="therapeuticIndications">
<p outputclass="therapeuticIndication">Some indication 1</p>
<p outputclass="therapeuticIndication">Some indication 2</p>
</sectiondiv>
</section>
</body>
</indications>
</drug>
片段 2:
<drug>
<title>Abacavir</title>
<indications outputclass="indicationsAndDose">
<title>Indications and dose</title>
<body>
<section outputclass="indicationAndDoseGroup">
<sectiondiv outputclass="therapeuticIndications">
<p outputclass="therapeuticIndication">Some indication 2</p>
</sectiondiv>
</section>
</body>
</indications>
</drug>
接受标准:
我需要输出一个 XML 片段,它是片段 1 和片段 2 的超集,但需要根据元素、属性和值以不同的方式完成。
- 当元素相同但值不同并且它们没有属性时,它们应该被合并,例如"Paracetamol" 和 "Abacavir"
- 当元素具有相同的属性时,它们应该是合并值,例如"Some indication 1"
解决方案应该是动态的,因为上述规则可以应用于任何类型的元素,即
<title>
<section>
<p>
等<drug> <title>Paracetamol</title> <indications outputclass="indicationsAndDose"> <title>Indications and dose</title> <body> <section outputclass="indicationAndDoseGroup"> <sectiondiv outputclass="therapeuticIndications"> <p outputclass="therapeuticIndication">Some indication 1</p> <p outputclass="therapeuticIndication">Some indication 2</p> </sectiondiv> </section> </body> </indications> </drug>
我不确定这是否是您想要的那种合并,因为您的要求很模糊!但是,它会根据您提供的输入生成输出:
declare variable $local:xml1 := document {
<drug>
<title>Paracetamol</title>
<indications outputclass="indicationsAndDose">
<title>Indications and dose</title>
<body>
<section outputclass="indicationAndDoseGroup">
<sectiondiv outputclass="therapeuticIndications">
<p outputclass="therapeuticIndication">Some indication 1</p>
</sectiondiv>
</section>
</body>
</indications>
</drug>
};
declare variable $local:xml2 := document {
<drug>
<title>Abacavir</title>
<indications outputclass="indicationsAndDose">
<title>Indications and dose</title>
<body>
<section outputclass="indicationAndDoseGroup">
<sectiondiv outputclass="therapeuticIndications">
<p outputclass="therapeuticIndication">Some indication 2</p>
</sectiondiv>
</section>
</body>
</indications>
</drug>
};
declare function local:merge($i1, $i2) {
if (node-name($i1) eq node-name($i2)) then
(
(: When elements are the same and the value is different
and they have no attributes they should be merged
e.g. "Paracetamol" and "Abacavir"
:)
if (empty(($i1/@*, $i2/@*))) then
element {node-name($i1)} {
$i1/@*,
$i1/text(),
let $ii1 := $i1/node()[1]
let $ii2 := $i2/node()[1]
return
if (not(empty($ii1)) and not(empty($ii2))) then
local:merge($ii1, $ii2)
else()
}
(: When the elements have the same attribute then they
should be merged value e.g. "Some indication 1"
:)
else if (fn:deep-equal($i1/@*, $i2/@*)) then
(
element {node-name($i1)} {
$i1/@*,
$i1/text(),
let $ii1 := $i1/node()[1]
let $ii2 := $i2/node()[1]
return
if (not(empty($ii1)) and not(empty($ii2))) then
local:merge($ii1, $ii2)
else()
},
if (not(empty($i1/text())) and not(empty($i2/text()))) then
element {node-name($i2)} {
$i2/@*,
$i2/text()
}
else()
)
else (),
let $ii1 := $i1/following-sibling::node()[1]
let $ii2 := $i2/following-sibling::node()[1]
return
if (not(empty($ii1)) and not(empty($ii2))) then
local:merge($ii1, $ii2)
else()
)
else()
};
local:merge($local:xml1/drug, $local:xml2/drug)