我在版本11.2中使用Oracle XE。
我有这样的XML:
<root>
<x a="a"/>
<x a="b"/>
<x a="c"/>
</root>
不,我想将属性b
添加到每个元素x
,其值取自序列,但它应为每个元素获取新值。预期结果是:
<root>
<x a="a" b="1"/>
<x a="b" b="2"/>
<x a="c" b="3"/>
</root>
我发现要向XML添加属性我可以使用insertchildxml
,但是在将序列中的相同(frist)值添加到所有属性b
中。我找不到如何为每个单独的元素x
调用此函数。
我将不胜感激任何帮助。
答案 0 :(得分:1)
我终于找到了一些解决方案,关键是使用XMLTable()函数。这是我的代码:
declare
v_inXML xmltype;
v_tmpXML xmltype;
v_withIdXML xmltype;
v_outXML xmltype;
BEGIN
v_inXML := XMLType('<root><x a="a"/><x a="b"/><x a="c"/></root>');
v_withIdXML := XMLType('<root/>');
v_outXML := XMLType('<root/>');
for c_rec in (
select *
from XMLTable('for $i in /root/x
return $i'
passing v_inXML
columns x xmltype path '/x'
)
)
loop
select insertchildxml(c_rec.x,'//x', '@b', pckg_ent_pk_seq.nextval) into v_tmpXML from dual;
select insertchildxml(v_withIdXML, '/root', 'x', v_tmpXML) into v_withIdXML from dual;
end loop;
select updatexml(v_outXML, '/root', v_withIdXML) into v_outXML from dual;
dbms_output.put_line(v_outXML.getClobVal());
END;
结果是:
<root><x a="a" b="92"/><x a="b" b="93"/><x a="c" b="94"/></root>
答案 1 :(得分:0)
这可以通过各种方式完成。选择取决于如何构建源数据,所需的输出格式等。
<强> 1。 XSLT转型
使用XMLTransform()
功能添加属性。
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转换为另一个,与上面基本相同的变体。
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并且可以在构造阶段注入序列属性值的情况。
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
如果您将已经构建的XML分解为具有XMLTable()
函数的记录,则最后一个方法也可以帮助构建XML。