我正在尝试使用XDocument
验证手动构建的XmlSchemaSet
。
此外,我想使用XmlPreloadedResolver
,以便我可以检索模式的本地副本并避免Web访问。
我添加了root schema的内容:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:enids="http://administracionelectronica.gob.es/ENI/XSD/v1.0/firma"
xmlns:enidocmeta="http://administracionelectronica.gob.es/ENI/XSD/v1.0/documento-e/metadatos"
xmlns:enifile="http://administracionelectronica.gob.es/ENI/XSD/v1.0/documento-e/contenido"
xmlns:enidoc="http://administracionelectronica.gob.es/ENI/XSD/v1.0/documento-e"
targetNamespace="http://administracionelectronica.gob.es/ENI/XSD/v1.0/documento-e"
elementFormDefault="qualified" attributeFormDefault="unqualified">
<xsd:annotation>
<xsd:documentation xml:lang="es">XSD DOCUMENTO ENI (v1.0)</xsd:documentation>
</xsd:annotation>
<xsd:import namespace="http://administracionelectronica.gob.es/ENI/XSD/v1.0/documento-e/metadatos" schemaLocation="metadatosDocumentoEni.xsd"/>
<xsd:import namespace="http://administracionelectronica.gob.es/ENI/XSD/v1.0/firma" schemaLocation="firmasEni.xsd"/>
<xsd:import namespace="http://administracionelectronica.gob.es/ENI/XSD/v1.0/documento-e/contenido" schemaLocation="contenidoDocumentoEni.xsd"/>
<xsd:element name="documento" type="enidoc:TipoDocumento">
<xsd:annotation>
<xsd:documentation xml:lang="es">El elemento "documento" podrá aparecer como elemento raíz de un documento XML objeto de intercambio o como elemento no raíz (elemento hijo).</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:complexType name="TipoDocumento">
<xsd:sequence>
<xsd:element ref="enifile:contenido"/>
<xsd:element ref="enidocmeta:metadatos"/>
<xsd:element ref="enids:firmas" minOccurs="0" maxOccurs="1">
<xsd:annotation>
<xsd:documentation xml:lang="es">La firma es obligatoria para el documento administrativo electrónico y para todo aquel documento electrónico susceptible de ser incorporado en un expediente electrónico.</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="Id" type="xsd:ID" use="optional"/>
</xsd:complexType>
</xsd:schema>
所以我为所有传递依赖项构建了一个XmlPreloadedResolver
,指向远程xsds的本地副本:
var resolver = new XmlPreloadedResolver();
resolver.add(
"http://administracionelectronica.gob.es/ENI/XSD/v1.0/documento-e/contenido",
File.ReadAllBytes("local/path/to/contenidoDocumentoEni.xsd"));
...
然后我创建一个包含根模式的SchemaSet
:
var settings = new XmlReaderSettings {
XmlResolver = resolver,
DtdProcessing = DtdProcessing.Parse
};
var schemaSet = new XmlSchemaSet();
using (var fs = new FileStream("./local/path/to/documentoEni.xsd", FileMode.Open))
using (var xr = XmlReader.Create(fs, settings))
{
schemaSet.Add(_enidoc.NamespaceName, xr);
}
schemaSet.Compile();
我收到XmlSchemaValidationException: the element http://administracionelectronica.gob.es/ENI/XSD/v1.0/documento-e/contenido:contenido is not declared
。
该元素是在第一个依赖项中定义的,所以我猜我没有正确创建XmlPreloadedResolver
或XmlSchemaSet
。
我认为模式是正确的,因为它们被无数的应用程序使用。
答案 0 :(得分:1)
显然XmlSchemaSet
需要将所有本地引用的模式添加到集合中,或XmlPreloadedResolver
无法解析为提供的URIs
。
我已设法通过以这种方式手动将模式添加到XmlSchemaSet
来实现它:
public static XmlSchemaSet SchemaSet() {
XNamespace enidoc =
"http://administracionelectronica.gob.es/ENI/XSD/v1.0/documento-e";
XNamespace enidocMeta =
"http://administracionelectronica.gob.es/ENI/XSD/v1.0/documento-e/metadatos";
XNamespace enids = "http://administracionelectronica.gob.es/ENI/XSD/v1.0/firma";
XNamespace enifile =
"http://administracionelectronica.gob.es/ENI/XSD/v1.0/documento-e/contenido";
XNamespace ds = "http://www.w3.org/2000/09/xmldsig#";
var namespaces =
new Dictionary < XNamespace, string > {
{ enidoc, "./Schemas/Eni/documentoEni.xsd"},
{ enidocMeta, "./Schemas/Eni/metadatosDocumentoEni.xsd"},
{ enids, "./Schemas/Eni/firmasEni.xsd"},
{ enifile, "./Schemas/Eni/contenidoDocumentoEni.xsd" },
{ ds, "./Schemas/Eni/xmldsig-core-schema.xsd" }
};
var schemaSet = new XmlSchemaSet();
foreach(var ns in namespaces) {
using(var fs = new FileStream(ns.Value, FileMode.Open))
using(var xr = XmlReader.Create(fs)) {
schemaSet.Add(ns.Key.NamespaceName, xr);
}
}
schemaSet.Compile();
return schemaSet;
}