这可以通过各种方式来完成。选择取决于源数据的构造方式、所需的输出格式等。
1. XSLT 转换
使用XMLTransform()
函数添加属性。
SQLFiddle test
with params as (
select
XMLParse( content
'
<root>
<x a="a"/>
<x a="b"/>
<x a="c"/>
</root>
'
) as doc_field
from dual
)
select
XMLTransform(
doc_field,
XMLParse( content
'
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<root>
<xsl:for-each select="child::*">
<xsl:apply-templates></xsl:apply-templates>
</xsl:for-each>
</root>
</xsl:template>
<xsl:template match="x">
<x a="{@a}" b="{position()}" />
</xsl:template>
</xsl:stylesheet>
'
)
)
from params
2. XQuery 返回单个 XML
使用XMLQuery()
函数单个 XML 可以转换为另一个与上述基本相同的变体。
SQLFiddle test
with params as (
select
XMLParse( content
'
<root>
<x a="a"/>
<x a="b"/>
<x a="c"/>
</root>
'
) as doc_field
from dual
)
select
XMLQuery(
'
<root>
{
for $x at $pos in $doc/root/x
return <x a="{$x/@a}" b="{$pos}" />
}
</root>
'
passing doc_field as "doc"
returning content
)
from params
3. 从行的顺序中获取值
此方法更好地匹配必须动态构建 XML 并且可以在构建阶段注入序列属性值的情况。
SQLFiddle test
with params as (
select 'a' a from dual union all
select 'b' a from dual union all
select 'c' a from dual
)
select
XMLElement("root",
XMLAgg(
XMLElement("x",
XMLAttributes(
a as "a",
rownum as "b"
)
)
)
)
from params
如果您将其分解为具有XMLTable()
功能的记录,最后一种方法也可以帮助处理已构建的 XML。