首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用XmlSchemaSet与XmlPreloadedResolver进行XDocument验证

使用XmlSchemaSet与XmlPreloadedResolver进行XDocument验证
EN

Stack Overflow用户
提问于 2016-09-13 12:44:40
回答 1查看 776关注 0票数 0

我正在尝试用XDocument验证手动构建的XmlSchemaSet。另外,我希望使用XmlPreloadedResolver,这样我就可以检索模式的本地副本并避免web访问。

我添加了根模式的内容

代码语言:javascript
复制
<?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,指向远程xsd的本地副本:

代码语言:javascript
复制
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,包括根模式:

代码语言:javascript
复制
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

该元素是在第一个依赖项中定义的,因此我猜我没有正确地创建XmlPreloadedResolverXmlSchemaSet

我认为模式是正确的,因为它们被无数的应用程序所使用。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-09-14 06:29:41

显然,XmlSchemaSet需要将所有本地引用的模式添加到集合中,或者XmlPreloadedResolver不解析到提供的URIs

通过以这种方式手动将模式添加到XmlSchemaSet中,我设法使其正常工作:

代码语言:javascript
复制
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;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39470455

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档