2014-10-09 2 views
0

Saxon을 사용하여 여러 스키마 파일에 대해 여러 XML 파일의 유효성을 검사 할 때 문제가 발생합니다. 여러 요소 사이에 존재하는 substitutionGroup 관계로 인해 문제가 발생합니다. 다음은 문제의 간단한 재구성입니다.첫 번째 파일의 유효성을 검사 한 후 substitutionGroup 멤버가 스키마에 추가 된 경우 Saxon으로 여러 xml 파일의 유효성을 검사 할 수 없습니다.

스키마는 다음과 같습니다

family.xsd

<?xml version="1.0" encoding="UTF-8"?> 
<schema targetNamespace="http://myexample/family" xmlns:fam="http://myexample/family" xmlns="http://www.w3.org/2001/XMLSchema"> 
    <element name="FamilyMember" type="string" /> 
    <element name="Parent" type="string" substitutionGroup="fam:FamilyMember"/> 
    <element name="Child" type="string" substitutionGroup="fam:FamilyMember"/> 
    <element name="Family"> 
    <complexType> 
     <sequence> 
     <element ref="fam:FamilyMember" maxOccurs="unbounded"/> 
     </sequence> 
    </complexType> 
    </element> 
</schema> 

family_ext.xsd

<?xml version="1.0" encoding="UTF-8"?> 
<schema targetNamespace="http://myexample/family_ext" xmlns:fam="http://myexample/family" xmlns="http://www.w3.org/2001/XMLSchema"> 
    <import namespace="http://myexample/family" schemaLocation="http://www.valid.nl/taxo3/family.xsd"/> 
    <element name="Cousin" type="string" substitutionGroup="fam:FamilyMember"/> 
</schema> 

두 개의 인스턴스 문서는 다음과 같습니다

family1.xml

여기

<Family xmlns="http://myexample/family" xmlns:fam2="http://myexample/family_ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://myexample/family_ext http://www.valid.nl/taxo3/family_ext.xsd" > 
    <Parent>John</Parent> 
    <Child>Alice</Child> 
    <fam2:Cousin>Pete</fam2:Cousin> 
</Family> 

438,953,210

family2.xml 문제이다 I 먼저 addSchemaSource 방법을 사용 색슨 구성에 family.xsd로드. 그런 다음 family1.xml의 유효성을 검사합니다. 이 작동합니다. 내가 처음 family2.xml을 확인하는 경우

In content of element <Family>: The content model does not allow element <Q{.../family_ext}Cousin> to appear immediately after element <{http://myexample/family}Child>. Expected <Q{.../family}FamilyMember> or nothing. 

그러나, 검증이 성공 (그리고 그때 family1.xml의 유효성을 검사하는 경우에도 성공) : 다음 family2.xml을 확인하려고하면, 나는 다음과 같은 오류가 발생합니다.

이 문제의 해결 방법은 유효성 검사간에 스키마 캐시를 지우는 것입니다. 그러나 이것은 실제 사용 사례에서 수십 개의 스키마가있는 캐시를 가지고 있기 때문에 계속로드하지 않아도되므로 궁극적으로 매우 만족스러운 솔루션은 아닙니다. 게다가 밸리데이션을 시작할 때, shemas의 총 컬렉션이 무엇인지는 아직 알지 못하기 때문에 선입 선행으로 모든 것을로드 할 수는 없습니다 (위 예제의 컨텍스트에서 family.xsd와 family_ext.xsd를로드 할 수 없습니다. 유효성 검사가 시작될 때).

유효성 검사를 수행하는 순서가 중요한 이유는 무엇입니까? 그리고 Saxon이 스키마 캐시를 지우지 않고 이러한 종류의 유효성 검사를 처리하도록하는 방법이 있습니까?

답변

0

Saxon은 두 번째 스키마 문서를로드 할 때 이미 유효성 검사에 사용 된 대체 그룹에 멤버를 추가 할 수 없다는 오류 메시지를 표시합니다. 그 이유는 스키마를 변경하면 이전 결과가 무효화되기 때문입니다. XSLT/XQuery 컨텍스트에서는 첫 번째 문서가 계속있을 수 있고 스키마 처리에서 파생 된 형식 주석이 처리 방법에 영향을 줄 수 있으므로 관련이 있습니다. 유효성 검사 시간에 사용 된 스키마 유형이 쿼리/변환 시간에 사용 된 스키마 유형과 크게 다른 경우 모든 종류의 문제가 발생할 수 있습니다. 따라서 귀하의 질문에 대한 대답은 (조립 된) 스키마를 사용하기 전에 모든 스키마 문서를 Saxon 구성으로로드해야한다는 것입니다. 실제로 규칙은 그만큼 엄격하지 않으므로 안전하게 변경할 수있는 많은 변경 사항이 있습니다. Saxon이 확인하고 방지하려고 시도하는 변경 사항은 대체 그룹의 구성원을 추가하고 기존 유형의 확장자로 파생 된 새로운 유형을 추가하는 것입니다. Saxon이 아마도 확인해야 할 다른 안전하지 않은 변경 사항이 있습니다. 예를 들어 X라는 새 전역 요소 선언을 추가하면 완연히 검증 된 경우 X라는 요소가 포함 된 콘텐츠가 무효화 될 수 있습니다.

대체 그룹에 추가 할 때 Saxon이 오류를보고하지 않는 이유를 모르겠습니다. 나는 그것을 조사 할 것이다.

실제로 여기서 발생하는 것은 패밀리 요소에 사용 된 익명 복합 유형이 유효성 검사 프로세스에 사용되는 유한 상태 기계로 컴파일된다는 것입니다. 이 FSM은 알려진 대체 그룹 구성원을 고려합니다. 새 대체 그룹 구성원이 추가되었음을 고려하지 않고 원래 요소가 새 요소를 확인하는 데 사용되는 것 같습니다.

나중에 : 나는 다음과 같이 재현하기 위해 노력했다 : SCH1, SCH2, DOC1 및 doc2이 예를 들어, 문서 및 스키마입니다

  Processor proc = new Processor(true); 
      SchemaManager sm = proc.getSchemaManager(); 
      sm.load(new StreamSource(new StringReader(sch1))); 
      System.err.println("Schema 1 OK"); 
      sm.newSchemaValidator().validate(new StreamSource(new StringReader(doc1))); 
      System.err.println("Doc 1 OK"); 
      sm.load(new StreamSource(new StringReader(sch2))); 
      System.err.println("Schema 2 OK"); 
      sm.newSchemaValidator().validate(new StreamSource(new StringReader(doc2))); 
      System.err.println("Doc 2 OK"); 

. 내가로드 SCH2에 기대하는 것을 얻을 :

net.sf.saxon.s9api.SaxonApiException: It is not possible to add to the 
substitution group of element FamilyMember in namespace 'http://myexample/family', 
because the schema for that namespace has already been used for validating instance 
documents, or for compiling queries or stylesheets 
+0

참고, 문제는 여기에 기록됩니다 https://saxonica.plan.io/issues/2174 –

+0

우리는 색슨의이 동작은 실제로 설명되어 있다는 것을 발견 [.NET api] (http://www.saxonica.com/documentation9.4-demo/dotnetdoc/Saxon/Api/SchemaManager.html)의 SchemaManager 클래스 (부끄러움이 자바 문서에도 존재하지 않는다!). 내가 예외적으로 예상 한 예외를 얻지 못하는 이유는 구성에 family_ext 스키마를 명시 적으로로드하지 않았기 때문이며 대신 Saxon이 schemaLocation 힌트를 통해 스키마를 발견하도록했기 때문입니다. 명시 적으로 스키마를로드하면 실제로 예외가 발생합니다. –

+0

확인. 스키마 위치 힌트에 의존하면 필요한 네임 스페이스 스키마가 이미 사용 가능하다는 이유로 무시됩니다. 나는 MULTIPLE_SCHEMA_IMPORTS 옵션이 어쨌든로드되도록 강요 하겠지만 인상을받지 못했습니다. –