[xml] XSD-어떤 순서로든 여러 번 요소를 허용하는 방법은 무엇입니까?

XSD를 만들고 다음 요구 사항으로 정의를 작성하려고합니다.

  • 지정된 하위 요소가 여러 번 표시되도록 허용 (0에서 제한 없음)
  • 자식 요소의 순서에 관계없이 허용

나는 주위를 둘러 보았다과 같은 다양한 솔루션 발견 :

<xs:element name="foo">
  <xsl:complexType>
    <xs:choice minOccurs="0" maxOccurs="unbounded">
      <xs:element name="child1" type="xs:int"/>
      <xs:element name="child2" type="xs:string"/>
    </xs:choice>
  </xs:complexType>
</xs:element>

그러나 내가 이해하는 바에서 xs : choice는 여전히 단일 요소 선택 만 허용합니다. 따라서 MaxOccurs를 이와 같이 제한되지 않음으로 설정하면 자식 요소 중 “하나”가 여러 번 나타날 수 있음을 의미합니다. 정확합니까?

위의 해결 방법이 잘못된 경우 요구 사항에서 위에서 언급 한 내용을 어떻게 얻을 수 있습니까?

편집 : 요구 사항이 다음과 같으면 어떻게합니까?

  • element child1 child2는 여러 번 나타날 수 있습니다 (0에서 제한 없음).
  • 순서에 관계없이 요소
  • child3 및 child4 요소는 정확히 한 번 표시되어야합니다.

예를 들어 다음 xml은 유효합니다.

<foo>
<child1> value </child1>
<child1> value </child1>
<child3> value </child3>
<child2> value </child2>
<child4> value </child4>
<child1> value </child1>
</foo>

그러나 이것은 아닙니다 (missing child3)

<foo>
<child1> value </child1>
<child1> value </child1>
<child2> value </child2>
<child4> value </child4>
<child1> value </child1>
</foo>



답변

스키마에서 질문에 child1있거나 child2임의의 순서로 여러 번 나타날 수 있습니다. 그래서 이것은 당신이 찾고있는 것 같습니다.

편집 : 그중 하나만 무제한으로 나타나게하려면 제한되지 않은 요소가 대신 요소로 이동해야합니다.

편집 : XML의 고정 유형.

편집 : maxOccurs에서 대문자 O

<xs:element name="foo">
   <xs:complexType>
     <xs:choice maxOccurs="unbounded">
       <xs:element name="child1" type="xs:int" maxOccurs="unbounded"/>
       <xs:element name="child2" type="xs:string" maxOccurs="unbounded"/>
     </xs:choice>
   </xs:complexType>
</xs:element>


답변

나중에 편집 할 때 추가 된 질문의 대체 공식은 아직 답이없는 것 같습니다. 요소의 자식 사이에 명명 된 child3, 명명 된 child4, 명명 된 번호 , child1또는 명명 된 번호 가 있어야하며 child2순서에 대한 제약없이 지정 하는 방법 아이들이 나타납니다.

이것은 간단하게 정의 할 수있는 정규 언어이며 필요한 콘텐츠 모델은 숫자 ‘3’과 ‘4’가 각각 정확히 한 번 발생하고 숫자 ‘1’과 ‘2가 나오는 문자열 세트를 정의하는 정규 표현식과 동형입니다. ‘는 여러 번 발생합니다. 이것을 작성하는 방법이 분명하지 않다면 그러한 언어를 인식하기 위해 어떤 종류의 유한 상태 머신을 구축 할 것인지 생각하는 것이 도움이 될 수 있습니다. 최소한 네 가지 상태가 있습니다.

  • ‘3’도 ‘4’도 보이지 않는 초기 상태
  • ‘3’은 보이지만 ‘4’는 보이지 않는 중간 상태
  • ‘4’는 보이지만 ‘3’은 보이지 않는 중간 상태
  • ‘3’과 ‘4’가 모두 보이는 최종 상태

자동 장치가 어떤 상태에 있든 ‘1’과 ‘2’를 읽을 수 있습니다. 그들은 기계의 상태를 변경하지 않습니다. 초기 상태에서는 ‘3’또는 ‘4’도 허용됩니다. 중간 상태에서는 ‘4’또는 ‘3’만 허용됩니다. 최종 상태에서는 ‘3’도 ‘4’도 허용되지 않습니다. 정규식의 구조는 ‘3’과 ‘4’만 발생하는 언어의 하위 집합에 대한 정규식을 먼저 정의하면 이해하기 가장 쉽습니다.

(34)|(43)

‘1’또는 ‘2’가 주어진 위치에서 여러 번 발생하도록 허용하려면 삽입 할 수 있습니다 (1|2)*(또는 [12]*정규식 언어가 해당 표기법을 허용하는 경우). 사용 가능한 모든 위치에이 표현식을 삽입하면

(1|2)*((3(1|2)*4)|(4(1|2)*3))(1|2)*

이것을 콘텐츠 모델로 번역하는 것은 간단합니다. 기본 구조는 정규식과 동일합니다 (34)|(43).

<xsd:complexType name="paul0">
  <xsd:choice>
    <xsd:sequence>
      <xsd:element ref="child3"/>
      <xsd:element ref="child4"/>
    </xsd:sequence>
    <xsd:sequence>
      <xsd:element ref="child4"/>
      <xsd:element ref="child3"/>
    </xsd:sequence>
  </xsd:choice>
</xsd:complexType>

의 제로 또는-더 많은 선택 삽입 child1하고하는 것은 child2간단합니다 :

<xsd:complexType name="paul1">
  <xsd:sequence>
    <xsd:choice minOccurs="0" maxOccurs="unbounded">
      <xsd:element ref="child1"/>
      <xsd:element ref="child2"/>
    </xsd:choice>
    <xsd:choice>
      <xsd:sequence>
        <xsd:element ref="child3"/>
        <xsd:choice minOccurs="0" maxOccurs="unbounded">
          <xsd:element ref="child1"/>
          <xsd:element ref="child2"/>
        </xsd:choice>
        <xsd:element ref="child4"/>
      </xsd:sequence>
      <xsd:sequence>
        <xsd:element ref="child4"/>
        <xsd:choice minOccurs="0" maxOccurs="unbounded">
          <xsd:element ref="child1"/>
          <xsd:element ref="child2"/>
        </xsd:choice>
        <xsd:element ref="child3"/>
      </xsd:sequence>
    </xsd:choice>
    <xsd:choice minOccurs="0" maxOccurs="unbounded">
      <xsd:element ref="child1"/>
      <xsd:element ref="child2"/>
    </xsd:choice>
  </xsd:sequence>
</xsd:complexType>

벌크를 약간 최소화하려면 child1및 반복 선택에 대해 명명 된 그룹을 정의 할 수 있습니다 child2.

<xsd:group name="onetwo">
  <xsd:choice>
    <xsd:element ref="child1"/>
    <xsd:element ref="child2"/>
  </xsd:choice>
</xsd:group>

<xsd:complexType name="paul2">
  <xsd:sequence>
    <xsd:group ref="onetwo" minOccurs="0" maxOccurs="unbounded"/>
    <xsd:choice>
      <xsd:sequence>
        <xsd:element ref="child3"/>
        <xsd:group ref="onetwo" minOccurs="0" maxOccurs="unbounded"/>
        <xsd:element ref="child4"/>
      </xsd:sequence>
      <xsd:sequence>
        <xsd:element ref="child4"/>
        <xsd:group ref="onetwo" minOccurs="0" maxOccurs="unbounded"/>
        <xsd:element ref="child3"/>
      </xsd:sequence>
    </xsd:choice>
    <xsd:group ref="onetwo" minOccurs="0" maxOccurs="unbounded"/>
  </xsd:sequence>
</xsd:complexType>

XSD 1.1에서는 all-groups 에 대한 일부 제약 이 해제되었으므로이 콘텐츠 모델을보다 간결하게 정의 할 수 있습니다.

<xsd:complexType name="paul3">
  <xsd:all>
    <xsd:element ref="child1" minOccurs="0" maxOccurs="unbounded"/>
    <xsd:element ref="child2" minOccurs="0" maxOccurs="unbounded"/>
    <xsd:element ref="child3"/>
    <xsd:element ref="child4"/>
  </xsd:all>
</xsd:complexType>

그러나 이전에 주어진 예에서 볼 수 있듯이 all그룹에 대한 이러한 변경 은 실제로 언어의 표현력을 변경하지 않습니다. 특정 언어의 정의를 더 간결하게 만들뿐입니다.


답변

이것이 마침내 나를 위해 일한 것입니다.

<xsd:element name="bar">
  <xsd:complexType>
    <xsd:sequence>
      <!--  Permit any of these tags in any order in any number     -->
      <xsd:choice minOccurs="0" maxOccurs="unbounded">
        <xsd:element name="child1" type="xsd:string" />
        <xsd:element name="child2" type="xsd:string" />
        <xsd:element name="child3" type="xsd:string" />
      </xsd:choice>
    </xsd:sequence>
  </xsd:complexType>
</xsd:element>


답변

그러나 내가 이해하는 바에서 xs : choice는 여전히 단일 요소 선택 만 허용합니다. 따라서 MaxOccurs를 이와 같이 제한되지 않음으로 설정하면 자식 요소 중 “하나”가 여러 번 나타날 수 있음을 의미합니다. 정확합니까?

아니요. 선택 xs:choice은로 인해 발생하는 모든 “반복”에 대해 개별적으로 발생합니다 maxOccurs="unbounded". 따라서 게시 한 코드는 정확하며 실제로 작성한대로 원하는 작업을 수행합니다.


답변

다음 스키마가 제안한 내용을 허용한다는 것을 알 수 있습니다.

  <xs:element name="foo">
    <xs:complexType>
      <xs:sequence minOccurs="0" maxOccurs="unbounded">
        <xs:choice>
          <xs:element maxOccurs="unbounded" name="child1" type="xs:unsignedByte" />
          <xs:element maxOccurs="unbounded" name="child2" type="xs:string" />
        </xs:choice>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

이렇게하면 다음과 같은 파일을 만들 수 있습니다.

<?xml version="1.0" encoding="utf-8" ?>
<foo>
  <child1>2</child1>
  <child1>3</child1>
  <child2>test</child2>
  <child2>another-test</child2>
</foo>

귀하의 질문과 일치하는 것 같습니다.


답변

위의 어느 것도 작동하지 않는 경우 HIPPA 스키마 또는 기타 복잡한 xsd에 대해 결과를 검증해야하는 EDI 추적 작업을 수행하고있을 것입니다. 요구 사항은 8 개의 REF 세그먼트가 있고 그 중 하나가 임의의 순서로 나타나야하고 모두가 필수는 아니라는 것입니다. 즉, 1st REF, 3rd REF, 2nd REF, 9th REF 순서대로 가질 수 있습니다. 기본 상황에서는 EDI 수신이 실패합니다. 기본 복합 유형은 다음과 같습니다.

<xs:sequence>
  <xs:element.../>
</xs:sequence>

굴절에 의해 요소를 호출 할 때 상황은 심지어 복잡하고 원래 지점의 요소 자체가 매우 복잡합니다. 예를 들면 :

<xs:element>
<xs:complexType>
<xs:sequence>
<element name="REF1"  ref= "REF1_Mycustomelment" minOccurs="0" maxOccurs="1">
<element name="REF2"  ref= "REF2_Mycustomelment" minOccurs="0" maxOccurs="1">
<element name="REF3"  ref= "REF3_Mycustomelment" minOccurs="0" maxOccurs="1">
</xs:sequence>
</xs:complexType>
</xs:element>

해결책:

여기서 단순히 “sequence”를 “all”로 바꾸거나 “choice”를 최소 / 최대 조합으로 사용하는 것은 작동하지 않습니다!

먼저 대체 "xs:sequence" with "<xs:all>"
요소를 참조하는 위치를 변경해야합니다.

<xs:annotation>
  <xs:appinfo>
    <b:recordinfo structure="delimited" field.........Biztalk/2003">

*** 이제 위의 세그먼트에서 다음과 같이 마지막에 트리거 지점을 추가합니다. trigger_field = “REF01 _… complete name ..”trigger_value = “38” “18”과 같이 트리거 값이 다른 다른 REF 세그먼트에 대해서도 동일하게 수행합니다. “,”XX “,”YY “등. 이제 레코드 정보가 다음과 같이 표시됩니다.b:recordinfo structure="delimited" field.........Biztalk/2003" trigger_field="REF01_...complete name.." trigger_value="38">


이렇게하면 각 요소가 고유하게됩니다. 이유는 모든 REF 세그먼트 (위 예)가 REF01, REF02, REF03과 같은 구조를 갖기 때문입니다. 그리고 유효성 검사 중에 구조 유효성 검사는 괜찮지 만 첫 번째 REF 자체에서 나머지 값을 찾으려고하기 때문에 값이 반복되지 않도록합니다. 트리거를 추가하면 모두 고유하게 만들어지며 모든 순서와 상황에 따라 전달됩니다 (예 : 9/9가 아닌 5/9 사용).

나는 이것에 거의 20 시간을 보냈기 때문에 도움이되기를 바랍니다.

행운을 빕니다


답변