如何将命名空间添加到 msxml DOMDocument?
How do I add a namespace to an msxml DOMDocument?
如何向 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");
接下来就是如何添加命名空间的问题了。
如何添加命名空间?
如果我采用显而易见的解决方案,在 Relationships 节点上设置一个名为 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
属性的其他元素。
namespaceURI 属性
我尝试设置 Relationships
元素的 namespaceURI
属性:
relationshps.namespaceURI := "http://schemas.openxmlformats.org/package/2006/relationships";
但是 属性 是 只读。
模式属性
该文档确实有一个 schemas
property, which gets or sets an 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
被发射。
与其尝试以正确的方式构建 XML 文档,我总是可以使用 StringBuilder
手动构建 XML,然后将其解析为 XML 文档对象。
但我宁愿以正确的方式去做。
诀窍是实现W3C DOM Level 2和Level 3有一个方法createElementNS
:
Creates an element with the specified namespace URI and qualified name.
Syntax
element = document.createElementNS(namespaceURI, qualifiedName);
但是 MSXML 6 仅支持 DOM 级别 1。
幸运的是,W3C DOM Level 1 确实有一个创建带有命名空间的元素的方法:createNode
:
Creates a node using the supplied type, name, and namespace.
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");
红利阅读
如何向 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");
接下来就是如何添加命名空间的问题了。
如何添加命名空间?
如果我采用显而易见的解决方案,在 Relationships 节点上设置一个名为 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
属性的其他元素。
namespaceURI 属性
我尝试设置 Relationships
元素的 namespaceURI
属性:
relationshps.namespaceURI := "http://schemas.openxmlformats.org/package/2006/relationships";
但是 属性 是 只读。
模式属性
该文档确实有一个 schemas
property, which gets or sets an 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
被发射。
与其尝试以正确的方式构建 XML 文档,我总是可以使用 StringBuilder
手动构建 XML,然后将其解析为 XML 文档对象。
但我宁愿以正确的方式去做。
诀窍是实现W3C DOM Level 2和Level 3有一个方法createElementNS
:
Creates an element with the specified namespace URI and qualified name.
Syntax
element = document.createElementNS(namespaceURI, qualifiedName);
但是 MSXML 6 仅支持 DOM 级别 1。
幸运的是,W3C DOM Level 1 确实有一个创建带有命名空间的元素的方法:createNode
:
Creates a node using the supplied type, name, and namespace.
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");