0

私は XSD に不慣れで、次の着信 XML メッセージを検証する XSD を作成するのが困難です。

私が抱えている困難は次のとおりです。

  1. 属性「position」の値が「FirstName」または「LastName」に等しいデータ要素「Field」が存在する必要があり、一度だけ表示されます。
  2. "MiddleName" に等しい属性 "position" 値を持つデータ要素 "Field" はオプションです。また、出現する場合は、一度しか出現できません。
  3. 日付要素「フィールド」には、これらの 3 つのサブ要素しかありません。「MiddleName」が存在しない場合は 2 つです。

それを行うアイデアはありますか?


検証に XSD が必要な受信元の XML。

<Message>  
  <MessageTypeIndicator version="1" class="8" function="2" origin="3"/>
  <Fields>
     <Field position="FirstName">Jason</Field>
     <Field position="LastName">Smith</Field>
     <Field position="MiddleName">dk</Field>
  </Fields>
</Message>

後で、元の XML を次のようなものに変換する XSLT も作成します。

<Person>
    <MessageTypeIndicator>
        <version>1</version>
        <class>8</class>
        <function>2</function>
        <origin>3</origin>
    </MessageTypeIndicator>
    <FirstName>Jason</FirstName>
    <LastName>Smith</LastName>
    <MiddleName>dk</MiddleName>
</Person>

以下は、検証なしでこれまでに作成した xslt です。

    <?xml version="1.0" encoding="UTF-8"?>

    <xsl:stylesheet>
      <xsl:output method="xml" encoding="UTF-8" indent="yes"/>
      <xsl:template match="/">
        <Message>      
          <MessageTypeIndicator>        
              <version>
                <xsl:value-of select="Message/MessageTypeIndicator/@version"/>
              </version>      
              <class>
                <xsl:value-of select="Message/MessageTypeIndicator/@class"/>            
              </class>      
              <function>
                <xsl:value-of select="Message/MessageTypeIndicator/@function"/>            
              </function>       
              <origin>
                <xsl:value-of select="Message/MessageTypeIndicator/@origin"/>            
              </origin>    
          </MessageTypeIndicator>
          <xsl:for-each select="Message/Fields/Field">
            <xsl:if test="@position='FirstName'">
              <FirstName>
              <xsl:value-of select="string(.)"/>
            </FirstName>
            </xsl:if>      
            <xsl:if test="@position='LastName'">
            <LastName>
              <xsl:value-of select="string(.)"/>
            </LastName>
            </xsl:if>      
            <xsl:if test="@position='MiddleName'">
            <MiddleName>
              <xsl:value-of select="string(.)"/>
            </MiddleName>
            </xsl:if>
          </xsl:for-each>
        </Message>
      </xsl:template>
    </xsl:stylesheet>
4

3 に答える 3

2

XSD 1.0 を実際に使用してこの種のチェックを行うことはできません。属性または要素が存在するかどうかをチェックすることはできますが、要素がその属性の特定の値とともに存在するかどうかはチェックできません。

かなり簡単にできることは、XSLT でチェックを行うことです。次のようなものです。

<xsl:template match="Message">
  <xsl:if test="count(Fields/Field[@position='FirstName']) != 1">
    <xsl:message terminate="yes">The message must exactly one 'FirstName' field</xsl:message>
  </xsl:if>
  <xsl:if test="count(Fields/Field[@position='MiddleName']) > 1">
    <xsl:message terminate="yes">The message cannot contain multiple 'MiddleName' fields</xsl:message>
  </xsl:if>
  <xsl:if test="count(Fields/Field[@position!='MiddleName']) > 3">
    <xsl:message terminate="yes">Too many fields</xsl:message>
  </xsl:if>
  <Person>
    <MessageTypeIndicator>
      <version>1</version>
      <class>8</class>
      <function>2</function>
      <origin>3</origin>
    </MessageTypeIndicator>
    <FirstName>
      <xsl:value-of select="Fields/Field[@position='FirstName']"/>
    </FirstName>
    <LastName>
      <xsl:value-of select="Fields/Field[@position='LastName']"/>
    </LastName>
    <MiddleName>
      <xsl:value-of select="Fields/Field[@position='MiddleName']"/>
    </MiddleName>
  </Person>
</xsl:template>

チェックしてから変換を行います。

于 2013-04-10T19:13:44.803 に答える
1

Message や Field などの非常に抽象的な要素名を使用し、MessageTypeIndicator や Position などの属性で特殊化することによって、このドキュメントを設計した人は、柔軟で拡張可能なものを設計することで賢いと考えたのでしょう。そうではありませんでした。次のような具体的な要素を使用する場合、XML はすでに非常に柔軟で拡張性があります。

<Person><First>Jason</First><Last>Smith</Last></Person>

余分なレベルの抽象化は、XML の処理を​​難しくする以外に何も達成しません。その 1 つの側面は、XML の正確なスキーマを作成できないことです。おそらくそれが実際に設計者が念頭に置いていたことです。おそらく彼らは、柔軟性と拡張性を維持したいと考えており、人々がスキーマを書き始めると、その柔軟性と拡張性が失われることを知っていました。

于 2013-04-10T19:40:52.437 に答える
1

この種の検証は、XSD 1.0 では実装できません。XSD 1.1の使用またはSchematronの使用を検討する必要があります。

于 2013-04-10T19:08:52.863 に答える