簡體   English   中英

如何使用正則表達式驗證XML模式的多個屬性

[英]How to validate the xml schema using regex for multiple attributes

我有一個需要驗證的XML文件,如下所示。

<?xml version="1.0" encoding="iso-8859-1"?>
    <MyAttributes
      Att1="00:00:00"
      Att2="00:05:00"
      Att3="00:05:00"
      Att4="foo,bar,true,true,,,0253d1f0-27d6-4d90-9d35-e396007db787"
      Att5="abc,def,false,true,,,4534234-65d6-6590-5535-da2007db787"
      ....
      ..../>

我想使用XSD模式文件來驗證xml文件,如下所示。

MyAttributes包含Att1,Att2和Att32。Att1,Att2和Att3的值的類型為TimeSpan3。MyAttributes中的所有其他屬性均為belwo格式。

  1. 所有其他屬性的格式如下csv格式,共7列
    第一和第二列應為非空字符串col3和col4應為布爾值
    col5和col6是字符串。可以為空col7應該是GUID類型

有沒有一種方法可以使用XSD 1.1通過某種正則表達式斷言來驗證這一點?

xs:time類型將驗證時間跨度字段。 對於其他字段,可以對帶有正則表達式的xs:string類型使用限制。 此XSD將驗證您發布的示例XML:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
    <xs:simpleType name="CsvType">
        <xs:restriction base="xs:string">
            <xs:pattern value="\w+,\w+,(true|false),(true|false),\w*,\w*,[A-Fa-f0-9]{7,8}(-[A-Fa-f0-9]{4}){3}-[A-Fa-f0-9]{11,12}"></xs:pattern>
        </xs:restriction>
    </xs:simpleType>
    <xs:element name="MyAttributes">
        <xs:complexType>
            <xs:attribute name="Att1" type="xs:time" />
            <xs:attribute name="Att2" type="xs:time" />
            <xs:attribute name="Att3" type="xs:time" />
            <xs:attribute name="Att4" type="CsvType" />
            <xs:attribute name="Att5" type="CsvType" />
        </xs:complexType>
    </xs:element>
</xs:schema>

您實際上並不需要XSD 1.1斷言,除非您要相對於另一個屬性驗證一個屬性的內容。

此正則表達式驗證您的TimeSpan行:

"(\d\d):(60|([0-5][0-9])):(60|([0-5][0-9]))"

正則表達式可視化

Debuggex演示

如果匹配,則該行有效。 我從這個問題的第一個答案中得到了正則表達式。

對於您的GUID行,如果此行與之匹配,那么它是有效的:

"(?:\\w+,){2}(?:(?:true|false),){2}(?:\\w*,){2}(?:[0-9a-fA-F]{7,8}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{11,12})"

正則表達式可視化

Debuggex演示

盡管演示輸入行中的第一個GUID與該問題中第一個答案的正則表達式匹配,但第二個GUID不匹配,因為它在某些元素中具有不同數量的字符。 我更改了它,使其同時匹配。

您可以使用xs:anyAttribute完全允許任何屬性,但是之后您將無法控制屬性的名稱或類型。 您只能為在架構中明確命名的屬性定義類型。 如您所建議,要處理一般情況,您將需要XSD 1.1斷言。 形式可以是:

test="every $a in @* satisfies (
        (name($a) = ('Att1', 'Att2', 'Att3') and $a castable as xs:time) or
        (matches(name($a), 'Att\d+') and matches($a, some-regex))"/>

其中some-regex是別人提供的正則表達式,以^開頭和$結尾,因此它匹配整個字符串而不是某些子字符串。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM