如何向IXMLDOMDocument
添加架构?
例如,我想生成XML:
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
<Relationship Id="rId1" Type="Frob" Target="Grob"/>
</Relationships>
我可以构造DOMDocument60对象(伪代码):
DOMDocument60 doc = new DOMDocument60();
IXMLDOMElement relationships = doc.appendChild(doc.createElement("Relationships"));
IXMLDOMElement relationship = relationships.appendChild(doc.createElement("Relationship"));
relationship.setAttribute("Id", "rId1");
relationship.setAttribute("Type", "Frob");
relationship.setAttribute("Target", "Grob");
现在出现了如何添加命名空间的问题。
如果我做了明显的解决方案,请在名为xmlns
的关系节点上设置属性:
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
通过以下方式:
relationships.setAttribute("xmlns",
"http://schemas.openxmlformats.org/package/2006/relationships");
保存文档时,会导致生成的xml错误:
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
<Relationship Id="rId1" Type="Frob" Target="Grob" xmlns=""/>
</Relationships>
它在每个其他元素上放置空xmlns
个属性。在这个小测试文档中,它只会将xmlns
误用于一个元素。在现实世界中,有几十个或几百万个具有空xmlns
属性的元素。
我尝试设置Relationships
元素的namespaceURI
属性:
relationshps.namespaceURI := "http://schemas.openxmlformats.org/package/2006/relationships";
但该属性是只读。
该文档具有schemas
属性,可获取或设置XMLSchemaCache
个对象。但它需要一个实际的架构文档。例如。试图设置一个架构并不起作用:
schemas = new XMLSchemaCache60();
schemas.add('', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main');
doc.schemas := schemas;
但是,它尝试实际加载架构URL,而不是加载架构,因为它不是URI。
也许我必须随机尝试其他事情:
schemas = new XMLSchemaCache60();
schemas.add('http://schemas.openxmlformats.org/spreadsheetml/2006/main', null);
doc.schemas := schemas;
但这不会导致发出xmlns
。
所以现在我放弃并询问Stackoverflow。
我可以使用StringBuilder
手动构建XML,然后将其解析为XML Document对象,而不是尝试以正确的方式构建XML文档。
但我宁愿以正确的方式去做。
答案 0 :(得分:1)
诀窍是要实现W3C DOM Level 2和3有一个方法createElementNS
:
创建具有指定名称空间URI和限定名称的元素。
语法
element = document.createElementNS(namespaceURI, qualifiedName);
但是,MSXML 6仅支持DOM Level 1。
幸运的是,W3C DOM Level 1确实有一种方法来创建一个带有命名空间的元素:createNode
:
使用提供的类型,名称和命名空间创建节点。
HRESULT createNode(VARIANT Type, BSTR name, BSTR namespaceURI, out IXMLDOMNode node);
因此,我的解决方案是我必须改变:
relationships: IXMLDOMElement = doc.createElement("Relationships");
成:
const NODE_ELEMENT: Integer = 1;
const ns: string = "http://schemas.openxmlformats.org/package/2006/relationships";
relationships: IXMLDOMElement = doc.createNode(NODE_ELEMENT, "Relationships", namespace);
一个糟糕的部分是必须在该命名空间中创建每个元素:
function AddElementNS(IXMLDOMNode parentNode, String tagName, String namespaceURI): IXMLDOMElement;
{
doc: IXMLDOMDocument = parentNode as IXMLDOMDocument;
if (doc == null)
doc = parentNode.ownerDocument;
if (namespaceURI <> "")
Result = doc.createNode(NODE_ELEMENT, tagName, namespaceURI)
else
Result = doc.createElement(tagName);
parentNode.appendChild(Result);
}
relationships: IXMLDOMElement = AddElementNS(doc, "Relationships", ns);
relationship: IXMLDOMElement = AddElementNS(relationships, "Relationship", ns);
relationship.setAttribute("Id", "rId1");
relationship.setAttribute("Type", "Frob");
relationship.setAttribute("Target", "Grob");