0

他の誰かの XSD 仕様に基づいて XML ファイルを作成していますが、それが検証されない理由がわかりません。

ルールは次のとおりです。

<xs:simpleType name="NonEmptyStringType">
    <xs:restriction base="xs:string">
        <xs:minLength value="1" />
        <xs:pattern value="[^\t\n\r]*[^\s][^\t\n\r]*" />
    </xs:restriction>
</xs:simpleType>

私は次のようにパターンを読みました:

  • [^\t\n\r]*タブ、改行、またはスペース以外のすべてに一致し、 0 回以上を返します
  • [^\s]スペース以外のものにマッチ
  • [^\t\n\r]*タブ、改行、またはスペース以外のすべてに一致し、 0 回以上を返します

そして、多くの不一致 xml の 1 つの次の例:

        <Zipcode>3506 RT</Zipcode>

xmllint によると、次のエラーで一致していません3506 RT(または3506RT、さらに言えば、一致すると予想される他の多くのもの)。

element Zipcode: Schemas validity error : Element '{http://www.reeleezee.nl/taxonomy/1.23}Zipcode': [facet 'pattern'] The value '3506 RT' is not accepted by the pattern '[^\t\n\r]*[^\s][^\t\n\r]*'.

私が正しく解釈していないことについてのヒントはありますか? (私は彼らの NonEmptyStringType の厳密さを理解していません.+を使用します)


要求に応じて、郵便番号の宣言を次に示します。

<xs:element name="Zipcode" minOccurs="0" nillable="true" rse:CanIgnore="true">
    <xs:annotation>
        <xs:documentation>Postcode</xs:documentation>
    </xs:annotation>
    <xs:simpleType>
        <xs:restriction base="NonEmptyStringType">
            <xs:maxLength value="10" />
        </xs:restriction>
    </xs:simpleType>
</xs:element>

ご覧のとおり、これは NonEmptyStringType のパターンにリンクしています (上記の最初のルール)。

4

3 に答える 3

3

この正規表現は私には問題ないようです。検証ツールのバグだと思います...エッジケースではしばしばバグがあります。

OK、確認しました: xerces はそれを受け入れます。xmllint が失敗します (xmllint を使用していたようです)。過去に xerces が正しく、xmllint が異常なケースで問題を抱えていることを何度か発見しました。そして、この正規表現は珍しいです。(私は実際に xmllint が大好きで、非常に高速ですが、xsd 仕様は巨大で複雑で紛らわしく、xmllint 関係者はまだすべてのエッジ ケースを解決していません)。

私が試した2つのオンラインバリデーターもそれを受け入れます: http://www.utilities-online.info/xsdvalidationhttp://www.freeformatter.com/xml-validator-xsd.html

ところで: xerces の Java バージョンをダウンロードしたところ、そのクラスjaxp.SourceValidatorが検証に最適なツールであることがわかりました。しかし、それはすでにJavaにある同じコードだと思います。


編集正規表現失敗する可能性があることを確認するために、xercesでさらにいくつかのテストを行いました(つまり、アクティブです)。がどこかにあると失敗します\n。(\t私はテストしませんでしたが、についても同じです\r)。

仕様を確認すると、 (この表\sでは )のように定義されています。これにより、正規表現が、またはどこにも持てないと言っていることが明らかになります。ただし、すべてのスペース文字ではない限り、リテラルスペース文字 ( ) を好きなだけ使用できます(つまり、それに一致するスペース以外の文字が少なくとも 1つある - ところで、それを として表記できます)。Xerces はこれを確認しています。すべてのスペースはエラーになります。[#x20\t\n\r]\t\n\r #x20[^\s]\S

スペース リテラル (パディングとインタースパーシングの両方) を許可したいのかもしれませんが、そこに何らかの値がある場合 (つまり、すべてのスペースではない場合) があります。

于 2013-01-28T11:46:40.633 に答える
1

[^\s] match anything that is not a space

しかし、入力文字列3506 RTにはスペースがあります!

それが失敗した理由だと思います:)[^\t\n\r]通過し3506た後、スペース文字を期待していません[^\s]が、表示されます! また[^\t\n\r]、次の文字セットがRT

したがって、宣言する必要があるのは次のとおりです。

<xs:pattern value="[^\t\n\r\s]*[\s][^\t\n\r\s]*" />

これで許可されます

  1. NOT \t, \n, \r and \s+ を追加したいパターンについてより厳密にする必要があるものはすべて、先頭に空白以外の文字が少なくとも 1 つある場合にのみ文字列を許可します。
  2. 空白文字: 次のように宣言することでオプションとして使用でき[\s]?ます.. where ? 一度だけ許可するか、まったく許可しません。そのため、スペース文字を繰り返すことはできません。
  3. 再びあるものは何でも NOT \t, \n, \r and \s

<xs:pattern value="[^\t\n\r\s]+[\s]?[^\t\n\r\s]*" />

[^\t\n\r\s]実際には、宣言を行うのではなく、数字と英字を検証することで、より厳密にすることができます..

それが役に立てば幸い!そして、あなたを悩ませている質問があれば教えてください。

于 2013-01-28T06:32:33.603 に答える
0

\r はスペースではないと思います。これは改行です (\n 改行に似ています)。これを \s または実際のリテラル " " に置き換えたいと思うかもしれません。

于 2013-01-27T19:12:35.143 に答える