2017-01-17 4 views
1

내 XML 구조는 다음과 같다 :이 구조에서XML 스키마 : keyref에 계층 적으로 낮은 요소

ROOT 
    |_ SetOfBandC (*) 
    |    |_ SetOfB (1) 
    |    |   |_ ElementB (*) 
    |    |   |_ ElementB__Key 
    |    |_ SetOfC (1) 
    |       |_ ElementC (*) 
    |       |_ ElementC__Key 
    |_ ElementD (*) 
    | 
    |_ SetOfBandC__Key 
    |_ ElementD__Key 
    | 
    |_ ElementD->SetOfBandC__Keyref 
    |_ ElementD->ElementB__Keyref 

내가 여러 수를 SetOfBandC뿐만 아니라 각 SetOfBandC 여러 ElementBElementC, 만 1 SetofBSetOfC로 .

문제는 ElementD 특정 SetOfBandC 그 세트의 ElementB를 참조하는 또 다른 하나를 참조하는 keyref이 있지만 XML 검사기가 ElementD->ElementB__Keyref의 타당성을 검사 할 때 그것은 단지 마지막SetOfBandC에서 검색하고,하지 않는 것이있다 그들 전부 또는 더 나은 것, ElementD->SetOfBandC__Keyref에 의해 참조 된 것. ElementD->ElementB__KeyrefElementB을 나타내며 마지막으로 SetOfBandC이 아닌 경우 유효성 검사가 작동하지 않습니다.

여기 내 ElementD->ElementB__Keyref입니다 :

<xs:keyref name="ElementD->ElementB__Keyref" refer="tns:ElementB__Key "> 
    <xs:selector xpath="tns:ElementD" /> 
    <xs:field xpath="@elementD_ref" /> 
</xs:keyref> 

그리고 내 ElementB__Key : TNS 내 대상 네임 스페이스입니다

<xs:key name="ElementB__Key"> 
    <xs:selector xpath="tns:ElementB" /> 
    <xs:field xpath="@elemB_name" /> 
</xs:key> 

. 내가 뭘 놓치고 있니?

추신 : 내 코드의 이름은 다르며 여기에 ->이 없습니다.

+0

올리기가 그렇게하지 선호하는 것 전체 스키마 – Sprotty

+0

@Sprotty을하지만 난 그것을 기록했다. – RVKS

답변

1

나는이 문제가 키의 범위라고 생각한다.

은 지금까지 내가 이해, 노드는 세계적으로 노드 이름에 의해, 또한가 속해있는 nffg의 이름으로뿐만 아니라 식별됩니다. 따라서 전 세계적으로 복합 키입니다. 정책은 nffg 이름과 노드 이름을 가진 노드를 나타냅니다. 현재 스키마에서 정책의 keyRef은이 두 키를 서로 독립적으로 만 참조하므로 XML 스키마는 함께 이동한다는 것을 알지 못합니다.

Nffg1-Node1과 같이 nffg 키 앞에 노드 키를 접두사로 사용하여 글로벌 고유 노드 이름을 사용하고 대신 정책에서 단일 키 참조로 사용하는 것이 좋습니다. 링크가 동일한 nffg 내의 소스 및 대상 노드 을 참조하는지 확인하려면 node에 대해 두 개의 키 정의가 필요합니다. keyRef (allNffgsAndPolicies)의 정책에 대한 하나, nffg에 로컬 인 하나 (nffg 아래) 링크 keyRef s에 대해. 당신이 사용할 수있는 - 키 두 xs:field 요소를 사용하여 -

약간 다른 대안은 노드에 nffgName 속성을 반복하고, 노드에 대한 글로벌 복합 키와 변경 nodeName 속성과 함께이를 사용하는 것입니다 정책. 노드의 로컬 nffgname 속성이 keykeyRef과 함께 상위 nffg의 속성과 일치하는지 확인해야합니다.

보너스 질문 : 여전히 원래 인스턴스와 스키마 인 Node3이 거부되었지만 다른 값이 허용되는 이유는 설명하지 않습니다. 두 하위 트리에있는 값에 오류가 발생할 것으로 예상했을 것입니다.specification에서는 노드 테이블에서 충돌하는 키가 노드 테이블에서 제거되지만이 경우 Node2 같은 키는 두 하위 트리 모두에서 충돌하므로 첫 하위 트리에만 표시되므로 Node3이 아닌 것처럼 충돌합니다. 여기에 반비례가 일어나며 마지막 자식 노드 테이블 만 최상위 노드 테이블에 포함되는 것으로 간주됩니다.

+0

멋진 아이디어에 감사드립니다. 안타깝게도 XML 파일과 일부 응용 프로그램에 의해 이미 사용 되었기 때문에 스키마의 많은 부분을 수정할 수 없습니다. 문제가되는 항목 인'srcNodeRef' 및'destNodeRef'를 만들기 위해 key/keyrefs 만 수정하는 것이 좋습니다. , 일. – RVKS

+0

의견을 보내 주셔서 감사합니다. RVKS. 이 추가 제한 조건을 충족시켜야하는 또 다른 대답을 게시했습니다. –

1

XML 스키마 1.1을 사용할 수있는 경우 다음은 XML 문서 또는 스키마 구조 자체의 수정없이 작동해야합니다.

<xs:element name="allNffgsAndPolicies"> 
    <xs:complexType> 
     <xs:sequence> 
      <!-- same content as in original schema --> 
     </xs:sequence> 
     <xs:assert test="every $i in tns:policy satisfies $i/@srcNode = tns:nffg/tns:nodes/tns:node/@nodeName and $i/@destNode = tns:nffg/tns:nodes/tns:node/@nodeName"/> 
    </xs:complexType> 
    <!-- other keys and keyRefs, only keep the first three --> 
</xs:element> 

나는 산소에서 성공적으로 테스트 할 수 :

  • allNffgsAndPolicies에 대한 복잡한 유형의 주장을 사용하는 대신 tns:policy

  • 모두 keyRef의 제거가 유효성을 검사 존재하지 않는 소스 또는 목적지 노드 이름을 사용하는 경우 유효성 검증에 실패합니다.

    xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" vc:minVersion="1.1" 
    

    는 여분의 마일을 이동하려면 : 그 꼭대기에, 당신은 또한 노드 이름이 내 존재하는지 확인하려면

    xs:schema 요소에 이러한 속성을 추가, XML 스키마 1.1을 활성화하려면 nffgRef와 정책에 의해 참조 nffg, 당신은 주장 조정할-미세 수 있습니다

    <xs:assert test=" 
        every $i in tns:policy satisfies 
        $i/@srcNode = tns:nffg[@nffgName eq $i/@nffgRef]/tns:nodes/tns:node/@nodeName 
        and 
        $i/@destNode = tns:nffg[@nffgName eq $i/@nffgRef]/tns:nodes/tns:node/@nodeName"/> 
    
+0

슬프게도 XML 스키마 1.1을 사용할 수 없습니다. 그러나 당신의 위대한 지원에 다시 한번 감사드립니다! 'keyref'로 그 일을 할 수있는 방법이 없다고 생각합니까? 심지어 첫 번째 솔루션, 모든 Nffgs에서 노드를 검색하고 뾰족한 노드가 아닌 노드를 검색하는 경우에도 괜찮습니다. – RVKS