我填充DOMDocumentFragment,目的是将其内容复制到目标DOMDocument中的多个位置。
我已经尝试了几乎所有我能想到的东西来实现这一目标,但它是一个史诗般的失败案例。以下简化的工作代码说明了我尝试过的一种方法:
declare
vTargetDoc dbms_xmldom.DOMDocument;
vFragDoc dbms_xmldom.DOMDocument;
vFrag dbms_xmldom.DOMDocumentFragment;
vAttachPointNodes dbms_xmldom.DOMNodeList;
vElt dbms_xmldom.DOMElement;
vTmpN dbms_xmldom.DOMNode;
begin
-- create the target document
vTargetDoc := dbms_xmldom.newDOMDocument(xmltype('<TargetDoc><AttachPoint></AttachPoint><AttachPoint></AttachPoint></TargetDoc>'));
-- create the source document to contain the fragment to be attached repeatedly
vFragDoc := dbms_xmldom.newDOMDocument();
-- create the fragment
vFrag := dbms_xmldom.createDocumentFragment(vFragDoc);
-- append element "A" to the fragment
vElt := dbms_xmldom.createElement(vFragDoc,'A');
vTmpN := dbms_xmldom.appendChild(dbms_xmldom.makeNode(vFrag),dbms_xmldom.makeNode(vElt));
-- identify all the attach points in the target document
vAttachPointNodes := dbms_xslprocessor.selectNodes(dbms_xmldom.makeNode(dbms_xmldom.getDocumentElement(vTargetDoc))
,'/TargetDoc/AttachPoint'
);
-- iterate through the attachpoints
for i in 0 .. dbms_xmldom.getLength(vAttachPointNodes) - 1 loop
-- import and attach the fragment to the current attachpoint
vTmpN := dbms_xmldom.appendChild(dbms_xmldom.item(vAttachPointNodes,i)
,dbms_xmldom.importNode(vTargetDoc
,dbms_xmldom.makeNode(vFrag)
,true
)
);
end loop;
-- print out the resultant target document XML
dbms_output.put_line(dbms_xmldom.getxmltype(vTargetDoc).getclobval());
end;
上面代码中值得注意的项目是:
此方法的目的是使用importNode从源文档中复制片段的内容,因为我需要将其附加到目标文档中。
好消息是它确实成功地将导入片段的内容复制到每个所需的附加点。
坏消息是它还在文档的末尾附加了导入片段的副本,如以下说明性输出所示:
<TargetDoc>
<AttachPoint>
<A/> EXPECTED
</AttachPoint>
<AttachPoint>
<A/> EXPECTED
</AttachPoint>
</TargetDoc>
<A/> UNEXPECTED
<A/> UNEXPECTED
(附加在文档末尾的2个FragmentContents副本是意外的)
我无法弄清楚为什么使用这种方法创建重复项,我也找不到任何其他有效的方法。
非常感谢任何帮助。谢谢!
答案 0 :(得分:1)
问题似乎是对dbms_xmldom.makeNode(vFrag)
的重复调用;你每次围绕循环再次这样做,这会创建另一个新节点,并且在那时你不会调用appendChild()
它似乎把它贴在某个看起来有点随机的地方。 / p>
您可以参考第一个电话的结果vTmpN
,而不是:
for i in 0 .. dbms_xmldom.getLength(vAttachPointNodes) - 1 loop
-- import and attach the fragment to the current attachpoint
vTmpN := dbms_xmldom.appendChild(dbms_xmldom.item(vAttachPointNodes,i)
,dbms_xmldom.importNode(vTargetDoc
--,dbms_xmldom.makeNode(vFrag)
,vTmpN
,true
)
);
end loop;
产生:
<TargetDoc>
<AttachPoint>
<A/>
</AttachPoint>
<AttachPoint>
<A/>
</AttachPoint>
</TargetDoc>
在这个示例中,您重新分配vTmpN
似乎并不重要 - 下一次循环仍然保留您想要的节点。您可能更喜欢使用单独的变量来保证安全(或更清晰)。