动态生成 XSD 时,XML 架构中的根元素定义不正确
Incorrect definition for the root element in XML schema when generating XSD on the fly
是的,我看了一下这个问题:Incorrect definition for the root element in XML schema
这是我的代码示例,它加载 XML 并根据动态生成的 XML 模式对其进行检查。
问题是:当我添加作为 DOM 文档对象生成的 XML 架构时,出现错误:
EOleException: /schema
Incorrect definition for the root element in XML schema
但是当我将 XSD dom 文档作为字符串重新加载到自身时:
xsd.loadXML(xsd.xml);
错误消失。
我还制作了 XSD 的 2 个调试输出:重新加载之前和之后。两个文件的字节到字节完全相同!!!
我不知道哪里出了问题,并假设当 XML 文档的字符串表示相同时,对象的结构也相同。
program XsdValidatorMCV;
uses
Winapi.MSXMLIntf, System.Win.ComObj, Winapi.ActiveX;
var
xsd: IXMLDOMDocument2;
xsdl: IXMLDOMSchemaCollection;
root: IXMLDOMElement;
el: IXMLDOMElement;
begin
CoInitialize(nil);
xsd := CreateOleObject('Msxml2.DOMDocument.6.0') as IXMLDOMDocument2;
xsdl := CreateOleObject('Msxml2.XMLSchemaCache.6.0') as IXMLDOMSchemaCollection;
try
xsd.appendChild(xsd.createProcessingInstruction('xml', 'version="1.0"'));
root := xsd.createElement('xs:schema');
root.setAttribute('xmlns:xs', 'http://www.w3.org/2001/XMLSchema');
xsd.appendChild(root);
el := xsd.createElement('xs:element');
root.appendChild(el);
el.setAttribute('name', 'data');
xsd.save('generated1.xsd'); //Debug output
//Workaround: reloading itself as string eliminates strange schema error:
//EOleException: /schema Incorrect definition for the root element in XML schema.
xsd.loadXML(xsd.xml);
xsd.save('generated2.xsd'); //Debug output
xsdl.add('', xsd); //Here is an error when without xsd.loadXML(xsd.xml)
finally
xsdl := nil;
xsd := nil;
end;
end.
问题是所有节点都缺少 namespaceURI
。它必须是http://www.w3.org/2001/XMLSchema
并且不会为每个新节点自动设置。
使用 MSXML 创建名称空间元素并不容易。代码量翻三倍:
const
NODE_ELEMENT = 1;
var
xsd: IXMLDOMDocument2;
xsdl: IXMLDOMSchemaCollection;
root: IXMLDOMNode;
el: IXMLDOMNode;
att: IXMLDOMAttribute;
begin
CoInitialize(nil);
xsd := CreateOleObject('Msxml2.DOMDocument.6.0') as IXMLDOMDocument2;
xsdl := CreateOleObject('Msxml2.XMLSchemaCache.6.0') as IXMLDOMSchemaCollection;
xsd.appendChild(xsd.createProcessingInstruction('xml', 'version="1.0"'));
root := xsd.createNode(NODE_ELEMENT, 'xs:schema', 'http://www.w3.org/2001/XMLSchema');
xsd.appendChild(root);
att := xsd.createAttribute('xmlns:xs');
att.value := 'http://www.w3.org/2001/XMLSchema';
root.attributes.setNamedItem(att);
el := xsd.createNode(NODE_ELEMENT, 'xs:element', 'http://www.w3.org/2001/XMLSchema');
root.appendChild(el);
att := xsd.createAttribute('name');
att.value := 'data';
el.attributes.setNamedItem(att);
xsdl.add('', xsd);
end.
更友好的版本:
const
XS_URI = 'http://www.w3.org/2001/XMLSchema';
function createSchemaNode(const parentNode: IXMLDOMNode; const name: WideString): IXMLDOMNode;
const
NODE_ELEMENT = 1;
var
doc: IXMLDOMDocument;
begin
if Supports(parentNode, IXMLDOMDocument) then
doc := parentNode as IXMLDOMDocument
else
doc := parentNode.ownerDocument as IXMLDOMDocument;
Result := doc.createNode(NODE_ELEMENT, 'xs:' + name, XS_URI);
parentNode.appendChild(Result);
end;
procedure setAttribute(const node: IXMLDOMNode; const name: WideString; value: OleVariant);
var
att: IXMLDOMAttribute;
doc: IXMLDOMDocument2;
begin
doc := node.ownerDocument as IXMLDOMDocument2;
att := doc.createAttribute(name);
att.value := value;
node.attributes.setNamedItem(att);
end;
var
xsd: IXMLDOMDocument2;
xsdl: IXMLDOMSchemaCollection;
root: IXMLDOMNode;
el: IXMLDOMNode;
begin
CoInitialize(nil);
xsd := CreateOleObject('Msxml2.DOMDocument.6.0') as IXMLDOMDocument2;
xsdl := CreateOleObject('Msxml2.XMLSchemaCache.6.0') as IXMLDOMSchemaCollection;
xsd.appendChild(xsd.createProcessingInstruction('xml', 'version="1.0"'));
root := createSchemaNode(xsd, 'schema');
setAttribute(root, 'xmlns:xs', XS_URI);
el := createSchemaNode(root, 'element');
setAttribute(el, 'name', 'data');
xsdl.add('', xsd);
end.
是的,我看了一下这个问题:Incorrect definition for the root element in XML schema
这是我的代码示例,它加载 XML 并根据动态生成的 XML 模式对其进行检查。
问题是:当我添加作为 DOM 文档对象生成的 XML 架构时,出现错误:
EOleException: /schema
Incorrect definition for the root element in XML schema
但是当我将 XSD dom 文档作为字符串重新加载到自身时:
xsd.loadXML(xsd.xml);
错误消失。
我还制作了 XSD 的 2 个调试输出:重新加载之前和之后。两个文件的字节到字节完全相同!!!
我不知道哪里出了问题,并假设当 XML 文档的字符串表示相同时,对象的结构也相同。
program XsdValidatorMCV;
uses
Winapi.MSXMLIntf, System.Win.ComObj, Winapi.ActiveX;
var
xsd: IXMLDOMDocument2;
xsdl: IXMLDOMSchemaCollection;
root: IXMLDOMElement;
el: IXMLDOMElement;
begin
CoInitialize(nil);
xsd := CreateOleObject('Msxml2.DOMDocument.6.0') as IXMLDOMDocument2;
xsdl := CreateOleObject('Msxml2.XMLSchemaCache.6.0') as IXMLDOMSchemaCollection;
try
xsd.appendChild(xsd.createProcessingInstruction('xml', 'version="1.0"'));
root := xsd.createElement('xs:schema');
root.setAttribute('xmlns:xs', 'http://www.w3.org/2001/XMLSchema');
xsd.appendChild(root);
el := xsd.createElement('xs:element');
root.appendChild(el);
el.setAttribute('name', 'data');
xsd.save('generated1.xsd'); //Debug output
//Workaround: reloading itself as string eliminates strange schema error:
//EOleException: /schema Incorrect definition for the root element in XML schema.
xsd.loadXML(xsd.xml);
xsd.save('generated2.xsd'); //Debug output
xsdl.add('', xsd); //Here is an error when without xsd.loadXML(xsd.xml)
finally
xsdl := nil;
xsd := nil;
end;
end.
问题是所有节点都缺少 namespaceURI
。它必须是http://www.w3.org/2001/XMLSchema
并且不会为每个新节点自动设置。
使用 MSXML 创建名称空间元素并不容易。代码量翻三倍:
const
NODE_ELEMENT = 1;
var
xsd: IXMLDOMDocument2;
xsdl: IXMLDOMSchemaCollection;
root: IXMLDOMNode;
el: IXMLDOMNode;
att: IXMLDOMAttribute;
begin
CoInitialize(nil);
xsd := CreateOleObject('Msxml2.DOMDocument.6.0') as IXMLDOMDocument2;
xsdl := CreateOleObject('Msxml2.XMLSchemaCache.6.0') as IXMLDOMSchemaCollection;
xsd.appendChild(xsd.createProcessingInstruction('xml', 'version="1.0"'));
root := xsd.createNode(NODE_ELEMENT, 'xs:schema', 'http://www.w3.org/2001/XMLSchema');
xsd.appendChild(root);
att := xsd.createAttribute('xmlns:xs');
att.value := 'http://www.w3.org/2001/XMLSchema';
root.attributes.setNamedItem(att);
el := xsd.createNode(NODE_ELEMENT, 'xs:element', 'http://www.w3.org/2001/XMLSchema');
root.appendChild(el);
att := xsd.createAttribute('name');
att.value := 'data';
el.attributes.setNamedItem(att);
xsdl.add('', xsd);
end.
更友好的版本:
const
XS_URI = 'http://www.w3.org/2001/XMLSchema';
function createSchemaNode(const parentNode: IXMLDOMNode; const name: WideString): IXMLDOMNode;
const
NODE_ELEMENT = 1;
var
doc: IXMLDOMDocument;
begin
if Supports(parentNode, IXMLDOMDocument) then
doc := parentNode as IXMLDOMDocument
else
doc := parentNode.ownerDocument as IXMLDOMDocument;
Result := doc.createNode(NODE_ELEMENT, 'xs:' + name, XS_URI);
parentNode.appendChild(Result);
end;
procedure setAttribute(const node: IXMLDOMNode; const name: WideString; value: OleVariant);
var
att: IXMLDOMAttribute;
doc: IXMLDOMDocument2;
begin
doc := node.ownerDocument as IXMLDOMDocument2;
att := doc.createAttribute(name);
att.value := value;
node.attributes.setNamedItem(att);
end;
var
xsd: IXMLDOMDocument2;
xsdl: IXMLDOMSchemaCollection;
root: IXMLDOMNode;
el: IXMLDOMNode;
begin
CoInitialize(nil);
xsd := CreateOleObject('Msxml2.DOMDocument.6.0') as IXMLDOMDocument2;
xsdl := CreateOleObject('Msxml2.XMLSchemaCache.6.0') as IXMLDOMSchemaCollection;
xsd.appendChild(xsd.createProcessingInstruction('xml', 'version="1.0"'));
root := createSchemaNode(xsd, 'schema');
setAttribute(root, 'xmlns:xs', XS_URI);
el := createSchemaNode(root, 'element');
setAttribute(el, 'name', 'data');
xsdl.add('', xsd);
end.