2016-09-13 7 views
0

Я пытаюсь проверить вручную построенный XDocument с XmlSchemaSet. Кроме того, я хочу использовать XmlPreloadedResolver, поэтому я могу получить локальную копию схем и избежать доступа к сети.Использование XmlSchemaSet с XmlPreloadedResolver для проверки XDocument

добавить содержание 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

Пожалуйста обеспечивают [mcve]. Недостаточно объявлений пространства имен; вам нужно 'xs: import's too, плюс множество других вещей может быть неправильным - действительно нужно опубликовать MCVE, поэтому нам не нужно начинать гадать. Благодарю. – kjhughes

+0

Да, вы совершенно правы. Дело в том, что я предполагаю, что схемы правы, потому что они используются многими приложениями (добавлено это предположение к тексту вопроса). Я подозреваю, что проблема в моем коде, и именно поэтому я попытался предоставить минимальную (надеясь достаточную) информацию. Скажите, пожалуйста, если все в порядке. Благодарю. – jruizaranguren

+0

Я не уверен, что XmlPreloadedResolver помогает при загрузке схемы, насколько я вижу в вашей основной схеме все URI-схемы «schemaLocation» являются относительными URI, поэтому я бы предположил, что когда вы делаете «schemaSet.Add» («http: // administracionelectronica» .gob.es/ENI/XSD/v1.0/documento-e "," mainSchema.xsd ")' с локальным расположением файловой системы, что все ссылочные схемы загружаются в любом случае из локальной файловой системы, не настраивая какой-либо конкретный преобразователь , Единственная проблема заключается в том, что одна схема ссылается на схему W3C с абсолютным URI http://www.w3.org/TR/xmldsig-core/xmldsig-core-schema.xsd. –

ответ

0

По всей видимости, 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; 
}