2016-09-13 3 views
0

XmlSchemaSet으로 수동으로 유효성 검사를 시도하고 있습니다. 또한 스키마의 로컬 복사본을 검색하고 웹 액세스를 피할 수 있도록 XmlPreloadedResolver을 사용하고 싶습니다. 그리고 나는 SchemaSet을 만들XmlPreloadedResolver와 함께 XmlSchemaSet을 사용하여 XDocument 유효성 검사

var resolver = new XmlPreloadedResolver(); 
resolver.add(
"http://administracionelectronica.gob.es/ENI/XSD/v1.0/documento-e/contenido", 
File.ReadAllBytes("local/path/to/contenidoDocumentoEni.xsd")); 
... 

:

<?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> 

그래서 내가 원격 XSD를의 로컬 복사본을 가리키는 모든 이적 의존성에 대한 XmlPreloadedResolver을 구축 :

은 내가 root schema의 내용을 추가 루트 스키마를 포함하여 :

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'도 필요하고 무수히 많은 다른 것들이 잘못 될 수 있습니다 - MCVE를 게시해야하므로 추측을 시작할 필요가 없습니다. 감사. – kjhughes

+0

예, 당신은 완전합니다. 문제는 많은 응용 프로그램에서 사용 중이기 때문에 스키마가 옳다고 가정한다는 것입니다 (이 가정을 질문 텍스트에 추가). 문제가 내 코드에있는 것 같아서 최소한의 정보 만 제공하려고했습니다. 지금 괜찮은지 말해주세요. 감사. – jruizaranguren

+0

XmlPreloadedResolver가 스키마 로딩에 도움이되는지 확신 할 수 없습니다. 기본 스키마에서 볼 수있는 모든 schemaLocation URI는 상대 URI이므로, 사용자가 'schemaSet.Add ("http : // administracionelectronica .gob.es/ENI/XSD /v1.0/documento -e ","mainSchema.xsd ")'를 사용하여 특정 파일 시스템 위치에서 로컬 파일 시스템에서 모든 참조 된 스키마를로드합니다. . 유일한 문제는 하나의 스키마가 절대 URI가있는 W3C 스키마를 참조한다는 것입니다. 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; 
} 
관련 문제