2

doc.xmlTimestamp属性を持つ単一のルート要素を含む単純なファイルがあります。

<?xml version="1.0" encoding="utf-8"?>
<root Timestamp="04-21-2010 16:00:19.000" />

schema.xsdタイムスタンプが正しい形式であることを確認するために、このドキュメントを私の単純なものに対して検証したいと思います。

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="root">
    <xs:complexType>
      <xs:attribute name="Timestamp" use="required" type="timeStampType"/>
    </xs:complexType>
  </xs:element>
  <xs:simpleType name="timeStampType">
    <xs:restriction base="xs:string">
      <xs:pattern value="(0[0-9]{1})|(1[0-2]{1})-(3[0-1]{1}|[0-2]{1}[0-9]{1})-[2-9]{1}[0-9]{3} ([0-1]{1}[0-9]{1}|2[0-3]{1}):[0-5]{1}[0-9]{1}:[0-5]{1}[0-9]{1}.[0-9]{3}" />
    </xs:restriction>
  </xs:simpleType>
</xs:schema>

そこで、lxml Pythonモジュールを使用して、簡単なスキーマ検証を実行し、エラーを報告しようとします。

from lxml import etree

schema = etree.XMLSchema( etree.parse("schema.xsd") )
doc = etree.parse("doc.xml")

if not schema.validate(doc):
    for e in schema.error_log:
        print e.message

XMLドキュメントが検証に失敗し、次のエラーメッセージが表示されます。

Element 'root', attribute 'Timestamp': [facet 'pattern'] The value '04-21-2010 16:00:19.000' is not accepted by the pattern '(0[0-9]{1})|(1[0-2]{1})-(3[0-1]{1}|[0-2]{1}[0-9]{1})-[2-9]{1}[0-9]{3} ([0-1]{1}[0-9]{1}|2[0-3]{1}):[0-5]{1}[0-9]{1}:[0-5]{1}[0-9]{1}.[0-9]{3}'.
Element 'root', attribute 'Timestamp': '04-21-2010 16:00:19.000' is not a valid value of the atomic type 'timeStampType'.

ですから、私の正規表現は間違っているに違いないようです。しかし、コマンドラインで正規表現を検証しようとすると、次のように渡されます。

>>> import re
>>> pat = '(0[0-9]{1})|(1[0-2]{1})-(3[0-1]{1}|[0-2]{1}[0-9]{1})-[2-9]{1}[0-9]{3} ([0-1]{1}[0-9]{1}|2[0-3]{1}):[0-5]{1}[0-9]{1}:[0-5]{1}[0-9]{1}.[0-9]{3}'
>>> assert re.match(pat, '04-21-2010 16:00:19.000')
>>> 

XSD正規表現にすべての機能があるわけではないことは承知していますが、私が見つけたドキュメントには、使用しているすべての機能が機能するはずであることが示されています。

では、私は何を誤解しているのでしょうか。また、なぜ私のドキュメントが失敗するのでしょうか。

4

2 に答える 2

3

あなた|のsはあなたが思っているよりも広く一致します。

(0[0-9]{1})|(1[0-2]{1})-(3[0-1]{1}|[0-2]{1}[0-9]{1})-[2-9]{1}[0-9]{3}

次のように解析されます:

(0[0-9]{1})
    -or-
(1[0-2]{1})-(3[0-1]{1}|[0-2]{1}[0-9]{1})-[2-9]{1}[0-9]{3}

それを避けたい場合は、より多くのグループを使用する必要があります。例えば

((0[0-9]{1})|(1[0-2]{1}))-((3[0-1]{1}|[0-2]{1}[0-9]{1}))-[2-9]{1}[0-9]{3} (([0-1]{1}[0-9]{1}|2[0-3]{1})):[0-5]{1}[0-9]{1}:[0-5]{1}[0-9]{1}.[0-9]{3}
于 2010-05-10T21:05:29.180 に答える
3

式にいくつかのエラーがあります。

  1. 00有効な月として許可します。
  2. A|BC一致Aし、BC-ではなくACBC。したがって、で始まる式は、〜(0[0-9]{1})|を含む任意の文字列と一致します。必要なのは、一致してからダッシュが続くことだけです。0009(0[1-9]|1[0-2])-0112
  3. 有効な日として許可00します。
  4. パターンはテキストの最初と最後に固定されていません-add^$。これが、Pythonを使用したテストが成功した理由です。

ちなみに、使ってみませんxs:dateTimeか?それは非常によく似た形式です-yyyy-mm-ddThh:mm:ss.fff私は思います。

于 2010-05-10T21:06:19.483 に答える