如何将非结构化xml转换为结构化&使用Xquery所需的表格,欣赏快速帮助。
以Section为根节点输入XML文件。
<Section>
<LowerAlpha>a</LowerAlpha>
<Number>1</Number>
<LowerAlpha>b</LowerAlpha>
<Number>1</Number>
<Roman>i</Roman>
<UpperAlpha>A</UpperAlpha>
<UpperAlpha>B</UpperAlpha>
<UpperAlpha>C</UpperAlpha>
<Roman>ii</Roman>
<Roman>iii</Roman>
<Number>2</Number>
<Number>3</Number>
<LowerAlpha>c</LowerAlpha>
<Number>1</Number>
<Number>2</Number>
<Roman>i</Roman>
</Section>
输出xml文件(Section - &gt; LowerAlpha - &gt; Number - &gt; Roman - &gt; UpperAlpha和包含在value标签中的数据。)
<Section>
<LowerAlpha>
<value>a</value>
<Number><value>1</value></Number>
</LowerAlpha>
<LowerAlpha>
<value>b</value>
<Number>
<value>1</value>
<Roman>
<value>i</value>
<UpperAlpha><value>A</value></UpperAlpha>
<UpperAlpha><value>B</value></UpperAlpha>
<UpperAlpha><value>C</value></UpperAlpha>
</Roman>
<Roman><value>ii</value></Roman>
<Roman><value>iii</value></Roman>
</Number>
<Number>2</Number>
<Number>3</Number>
</LowerAlpha>
<LowerAlpha><value>c</value>
<Number><value>1</value></Number>
<Number><value>2</value>
<Roman><value>i</value></Roman>
</Number>
</LowerAlpha>
</Section>
答案 0 :(得分:1)
使用递归。该解决方案与XSLT有一些相似之处,但增加了逻辑以遵循特定于应用程序的嵌套规则。但是,它应该足够通用以适应其他嵌套规则:
declare function local:passthru(
$e as element(),
$restrict as xs:QName*
) {
element { node-name($e) } {
for $n in $e/*[if (exists($restrict)) then
node-name(.) = $restrict else true()]
return local:process($n)
}
};
declare function local:value-wrap(
$e as element()
) {
element { node-name($e) } {
element value {
$e/node()
}
}
};
declare function local:nest(
$e as element(),
$restrict as xs:QName*
)
{
element { node-name($e) } {
element value { $e/string() },
let $next := ($e/following-sibling::*[node-name(.) eq node-name($e)])[1]
let $children := document{ $e/following-sibling::*[
if (empty($next)) then true() else . << $next] }/*
for $c in $children[if (exists($restrict)) then
node-name(.) = $restrict else true()]
return local:process($c)
}
};
declare function local:process(
$e as item()
) as item()?
{
typeswitch ($e)
case element(Section) return local:passthru($e, xs:QName('LowerAlpha'))
case element(Number) return local:nest($e, (xs:QName('Roman')))
case element(LowerAlpha) return local:nest($e, xs:QName('Number'))
case element(Roman) return local:nest($e, xs:QName('UpperAlpha'))
case element(UpperAlpha) return local:value-wrap($e)
default return ()
};
local:process(**Input XML**)
输出:
<Section>
<LowerAlpha>
<value>a</value>
<Number>
<value>1</value>
</Number>
</LowerAlpha>
<LowerAlpha>
<value>b</value>
<Number>
<value>1</value>
<Roman>
<value>i</value>
<UpperAlpha>
<value>A</value>
</UpperAlpha>
<UpperAlpha>
<value>B</value>
</UpperAlpha>
<UpperAlpha>
<value>C</value>
</UpperAlpha>
</Roman>
<Roman>
<value>ii</value>
</Roman>
<Roman>
<value>iii</value>
</Roman>
</Number>
<Number>
<value>2</value>
</Number>
<Number>
<value>3</value>
</Number>
</LowerAlpha>
<LowerAlpha>
<value>c</value>
<Number>
<value>1</value>
</Number>
<Number>
<value>2</value>
<Roman>
<value>i</value>
</Roman>
</Number>
</LowerAlpha>
</Section>