2016-09-13 5 views
0

XDocumentXmlSchemaSetで手動で検証しようとしています。 また、XmlPreloadedResolverを使用したいので、私はスキーマのローカルコピーを取得してWebアクセスを避けることができます。XmlPreloadedResolverでXmlSchemaSetを使用して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> 

だから私は、リモートのXSDのローカルコピーを指して、すべての推移的依存関係のためXmlPreloadedResolverを構築:

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も必要ですし、他にも何かが間違っている可能性があります - 私たちが推測を開始する必要がないようにMCVEを投稿する必要があります。ありがとう。 – kjhughes

+0

はい、あなたは完全に正しいです。問題は、多くのアプリケーションで使用されているため、スキーマが正しいと仮定していることです(この仮定を質問テキストに追加しました)。私は問題が私のコードの中にあると思うので、私は最小限の(十分な情報を得るために)情報を提供しようとしたのです。今は大丈夫なら教えてください。ありがとう。 – jruizaranguren

+0

XmlPreloadedResolverがスキーマの読み込みに役立つかどうかわかりませんが、主なスキーマではすべてのschemaLocationのURIが相対URIであるため、 'schemaSet.Add(" http:// administracionelectronica .gob.es/ENI/XSD/v1.0/documento-e "、" mainSchema.xsd ")'をローカルファイルシステムの場所に置き換えて、特定のリゾルバを設定せずに参照されたすべてのスキーマがローカルファイルシステムからロードされるようにします。唯一の問題は、1つのスキーマが絶対URI http://www.w3.org/TR/xmldsig-core/xmldsig-core-schema.xsdでW3Cスキーマを参照することです。 –

答えて

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; 
} 
関連する問題