2016-06-07 4 views
0

알 수없는 깊이의 XML을 확인하기 위해 XSD를 생성하려고합니다. 이 작업은 XML의 XSLT를 통해 수행됩니다. XML은 클래스 설명처럼 다소 구조화되어 있으며 모든 노드에는 특성 및 하위에 대한 정보가 들어 있습니다. XSD는 인스턴스가 들어있는 다른 XML을 확인해야합니다. 따라서 XSD는 인스턴스가 클래스의 모든 속성을 가지고 있고 조상이라고 판단해야합니다.XSD 여러 수준의 확장 문제

그래서 나는 서로를 확장하는 유형으로 내 문제를 해결하려고했습니다.

XML 테스트 파일 :

<!-- language:xml --> 
<?xml version="1.0" encoding="UTF-8"?> 
<CAEXFile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      FileName="Visu_Ruehrreaktor.aml" 
      SchemaVersion="2.15" 
      xsi:noNamespaceSchemaLocation="Validation.xsd"> 
    <HMI> 
     <HMIGraphic Name="Visu_Ruehrreaktor" 
        RefBaseSystemUnitPath="HMISUCLib/Graphic" 
        ID="dce863ca-795b-4d54-9a4c-789b0204f243"> 
     <h>1080</h> 
     <w>1920</w> 
     <HMIVisuObjectTextBoxTermination Name="Text01" 
              RefBaseSystemUnitPath="HMISUCLib/VisuObject/TextBox/Termination" 
              ID="c0215848-b8b6-4f76-aa2c-3996a053f3fc"> 
      <text/> 
      <tagname>Text01</tagname> 
      <x>178</x> 
      <y>152</y> 
      <h>37</h> 
      <w>139</w> 
      <role/> 
      <type>0001</type> 
      <rotation>01</rotation> 
      <com_id/> 
     </HMIVisuObjectTextBoxTermination> 
     </HMIGraphic> 
    </HMI> 
</CAEXFile> 

XSD :

<?xml version="1.0" encoding="UTF-8"?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
      xmlns:fn="http://www.w3.org/2005/xpath-functions"> 
    <xs:complexType name="HMI_type"> 
     <xs:choice maxOccurs="unbounded"> 
     <xs:element name="HMIGraphic" type="HMIGraphic_type" minOccurs="0"/> 
     </xs:choice> 
    </xs:complexType> 

    <xs:complexType name="HMIVisuObject_type"> 
     <xs:choice maxOccurs="unbounded"> 
     <xs:element name="tagname" minOccurs="1" maxOccurs="1"/> 
     <xs:element name="x" minOccurs="1" maxOccurs="1"/> 
     <xs:element name="y" minOccurs="1" maxOccurs="1"/> 
     <xs:element name="h" minOccurs="1" maxOccurs="1"/> 
     <xs:element name="w" minOccurs="1" maxOccurs="1"/> 
     <xs:element name="role" minOccurs="1" maxOccurs="1"/> 
     <xs:element name="type" minOccurs="1" maxOccurs="1"/> 
     <xs:element name="rotation" minOccurs="1" maxOccurs="1"/> 
     </xs:choice> 
     <xs:attribute name="Name" type="xs:string" use="required"/> 
     <xs:attribute name="RefBaseSystemUnitPath" type="xs:string" use="required"/> 
     <xs:attribute name="ID" type="xs:string" use="required"/> 
    </xs:complexType> 

    <xs:complexType name="HMIVisuObjectTextBox_type"> 
     <xs:complexContent> 
     <xs:extension base="HMIVisuObject_type"> 
      <xs:choice maxOccurs="unbounded"> 
       <xs:element name="text" minOccurs="1" maxOccurs="1"/> 
      </xs:choice> 
     </xs:extension> 
     </xs:complexContent> 
    </xs:complexType> 
    <xs:complexType name="HMIVisuObjectTextBoxTermination_type"> 
     <xs:complexContent> 
     <xs:extension base="HMIVisuObjectTextBox_type"> 
      <xs:choice maxOccurs="unbounded"> 
      </xs:choice> 
     </xs:extension> 
     </xs:complexContent> 
    </xs:complexType> 
    <xs:complexType name="HMIGraphic_type"> 
     <xs:choice maxOccurs="unbounded"> 
     <xs:element name="HMIVisuObject" type="HMIVisuObject_type" minOccurs="0"/> 
     <xs:element name="HMIVisuObjectTextBox" 
        type="HMIVisuObjectTextBox_type" 
        minOccurs="0"/> 
     <xs:element name="HMIVisuObjectTextBoxTermination" 
        type="HMIVisuObjectTextBoxTermination_type" 
        minOccurs="0"/> 
     <xs:element name="h" minOccurs="1" maxOccurs="1"/> 
     <xs:element name="w" minOccurs="1" maxOccurs="1"/> 
     </xs:choice> 
     <xs:attribute name="Name" type="xs:string" use="required"/> 
     <xs:attribute name="RefBaseSystemUnitPath" type="xs:string" use="required"/> 
     <xs:attribute name="ID" type="xs:string" use="required"/> 
    </xs:complexType> 

    <xs:element name="CAEXFile"> 
     <xs:complexType> 
     <xs:all> 
      <xs:element name="HMI" type="HMI_type" minOccurs="0"/> 
     </xs:all> 
     <xs:anyAttribute processContents="skip"/> 
     </xs:complexType> 
    </xs:element> 
</xs:schema> 

문제는 그 유효성 검사를 실행하고 유형의 요소를 찾아 그 어느 때 HMIVisuObjectTextBoxTermination_type 내가 말하는 오류가 발생한다 을 그 텍스트은 요소로 사용할 수 없습니다.

출력/To_Check.aml : 15 : 요소 텍스트 : 스키마 유효성 오류 : 요소 'text':이 요소는 필요하지 않습니다. 예상되는 것은 (tagname, x, y, h, w, 역할, 유형, 순환) 중 하나입니다.

기본적으로이 유형의 체인의 루트 요소 요소 만. 내가 뭘 잘못하고 어떻게이 문제를 해결할 수 있습니다. 사전

+0

두 파일을 모두 추가했습니다. 나는 그것이 도움이되기를 바랍니다. – Tyreal

답변

0

HMIVisuObjectTextBoxTermination_type 아마 당신이 기대하는 것이 아니다 효과적인 컨텐츠 모델을 가지고 귀하의 복합 형의

감사합니다. XSD 1.0에서 복합 유형의 확장은 먼저 기본 유형의 내용 모델을 포함하는 시퀀스를 만든 다음 확장에 의해 추가 된 재료를 포함합니다. (어떤 사람들은 OO 언어의 기본 클래스를 확장하여 구조 끝에 새로운 필드를 추가하는 것과 비슷한 것으로 생각하는 것이 도움이된다는 것을 알게됩니다.) 확장의 확장이 있기 때문에, 가지고있는 것은 다음과 같습니다. 효과 :

<xs:sequence> 
    <!--* complex type HMIVisuObjectTextBox_type *--> 
    <xs:sequence> 
    <!--* complex type HMIVisuObject_type *--> 
    <xs:choice maxOccurs="unbounded"> 
     <xs:element name="tagname" minOccurs="1" maxOccurs="1"/> 
     <xs:element name="x" minOccurs="1" maxOccurs="1"/> 
     <xs:element name="y" minOccurs="1" maxOccurs="1"/> 
     <xs:element name="h" minOccurs="1" maxOccurs="1"/> 
     <xs:element name="w" minOccurs="1" maxOccurs="1"/> 
     <xs:element name="role" minOccurs="1" maxOccurs="1"/> 
     <xs:element name="type" minOccurs="1" maxOccurs="1"/> 
     <xs:element name="rotation" minOccurs="1" maxOccurs="1"/> 
    </xs:choice> 
    <xs:choice maxOccurs="unbounded"> 
     <xs:element name="text" minOccurs="1" maxOccurs="1"/> 
    </xs:choice> 
    </xs:sequence> 
    <xs:choice maxOccurs="unbounded"> 
    </xs:choice> 
</xs:sequence> 

유효 인스턴스는 세 개의 서브 시퀀스들의 연쇄적인 요소의 시퀀스를 포함해야하는 매치 :

  • 한 제 또는 태그 이름, X, Y의보다, H, w, 역할 유형 또는 회전이 뒤 따르고
  • 텍스트 중 하나 이상이 뒤 따르고
  • 빈 세트 중 하나 이상.

여기서 두 가지 문제가있다 : 첫째, XML로 볼때, 당신의 반복 선택 가능한 어린이 세트에 추가 할 다른 모든 후에 올 필요하지 text을 기대했다. 둘째, 다음 입력 항목이 하위 항목 중 하나와 일치 할 때 콘텐츠 모델의 선택 항목이 충족됩니다. 빈 선택에는 자녀가 없으므로 아무 것도 자녀와 일치 할 수 없습니다. 선택의 여지가있는 경우,이 순서의 세 번째 선택 사항으로 선택이 만족스럽지 않습니다. 즉, 포함하는 시퀀스가 ​​만족스럽지 않다는 것을 의미합니다. 즉 시퀀스를 포함하는 시퀀스가 ​​만족스럽지 않음을 의미합니다. 이는 다시 HMIVisuObjectTextBoxTermination_type 유형이 유효하지 않음을 의미합니다. minOccurs="0"을 선택하면 유형이 유효한 인스턴스를 가질 수 있지만 text 요소를 먼저 가져올 수는 없습니다.

OP는 "모든 부모 특성을 복사하고 새로운 형식을 만드는 방식으로 내 XSLT를 재귀 적으로 만들려고 시도하는 것보다 다른 방법이 있습니까?"기본적으로 원하는 것은 무엇입니까? do는 실제로 선택 목록에 텍스트를 추가합니다. 왜냐하면 모두 XML에 존재해야하지만 어떤 순서로도 될 수 있기 때문입니다. "

몇 가지 가능한 방법은 자신을 제공 :

  • 은 어린이를위한 고정 된 순서를 지정합니다. 자식 시퀀스가 ​​고정되어 있으면 타입 유도 문제는 간단 해집니다.

    그래서 어린이의 순서는 제약을받지 않아야한다는 전제를 매우 신중하게 검토합니다. 이것은 사실보다 훨씬 자주 주장됩니다. 아이들의 순서가 (자연 언어 문서에서 일반적으로하는 것처럼) 정보를 전달한다면 그것은 사실입니다. 시퀀스가 정보를 전달하지 않으면 의심 스럽습니다.

  • HMIVisuObject_type, HMIVisuObjectTextBox_type 등에서 선택 항목에 대한 명명 된 모델 그룹을 정의하십시오. 해당 이름이 지정된 모델 그룹 중 선택 항목으로 다양한 유형을 정의하십시오.

    <xs:group name="A"> 
        <xs:element ref="tagname"/> 
        <xs:element ref="x"/> 
        <xs:element ref="y"/> 
        ... 
    </ 
    <xs:group name="B"> 
        <xs:element ref="text"/> 
        ... 
    </ 
    <xs:group name="C"> 
        ... 
    </ 
    
    <xs:complexType name="HMIVisuObject_type"> 
        <xs:choice minOccurs="0" maxOccurs="unbounded" ref="A"/> 
        ... 
    </ 
    <xs:complexType name="HMIVisuObjectTextBox_type"> 
        <xs:choice minOccurs="0" maxOccurs="unbounded"> 
        <xs:choice ref="A"/> 
        <xs:choice ref="B"/> 
        </ 
        ... 
    </ 
    <xs:complexType name="HMIVisuObjectTextBoxTermination_type"> 
        <xs:choice minOccurs="0" maxOccurs="unbounded"> 
        <xs:choice ref="A"/> 
        <xs:choice ref="B"/> 
        <xs:choice ref="C"/> 
        </ 
        ... 
    </ 
    

    이것은 세 가지 유형 간의 관계를 사람 독자에게 명확하게 나타내며 동일한 것의 여러 사양을 피합니다. 유형 사이의 기본 유형/파생 형식 관계 및 덜 도움이되는 일부 환경에서는 관계를 나타내지 않습니다. (그러나 OO 클래스 시스템으로의 매핑에 의존했다면, 처음에는 반복적 인 선택을 사용하지 않을 것입니다. 따라서 일부 사용자에게는 중요하지만 문제는 아닐 것입니다.)

  • 유형 계층을 반전하십시오 : 가장 포괄적 인 유형을 유형으로 정의하고 다른 유형은 제한으로 정의하십시오.

    이것은 기본/파생 링크를 사용하는 유형 간의 관계를 나타내지 만, 직접 연결은 원하는 방향이 아닐 수 있습니다.

  • XSD 1.1을 사용하는 경우이 유형의 선택 사항을 모든 그룹으로 바꿉니다. XSD 1.1에서 모든 그룹에 의해 확장되는 모든 그룹을 가진 기본 유형은 더 큰 모든 그룹을 생성합니다.

+0

그렇게 좋지는 않지만 지금까지 감사드립니다. XSLT에서 빈 세트를 수정할 수 있습니다. 하지만 그건 내 문제가 시퀀스와 함께 해결되지 않습니다. 그래서 모든 부모 특성을 복사하고 새로운 형식을 만들고 솔루션을 잊어 버리는 방식으로 내 XSLT를 재귀 적으로 만들려고 시도하는 것보다 다른 방법이 있습니까? 기본적으로 선택 사항 목록에 텍스트를 추가하는 것은 XML에 존재해야하지만 순서는 다를 수 있기 때문에 텍스트를 실제로 추가하는 것입니다. – Tyreal