我可以在XML Schema元素名称中使用正则表达式吗?

时间:2012-12-18 14:52:11

标签: xml xsd

我正在尝试为我传递的一段代码生成的XML创建XML Schema。我将描述我的问题的简化版本。假设这段代码生成的XML文件描述了一个文本文档;它看起来像这样:

<document>
  <r1>A line of text</r1>
  <r2 style="bold">Another line which is bold</r2>
  <r3>Yet another line</r3>
</document>

等等。我知道不是最好的设计 - 如果行号是属性会更好,但这就是我必须使用的。它代表了行号,这就是问题所在。有没有办法编写一个Schema,让我为元素名称指定正则表达式(或类似的)?我希望XSD文件看起来像这样:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
        targetNamespace="http://www.example.org/SimpleSchema" 
        xmlns:tns="http://www.example.org/SimpleSchema" 
        elementFormDefault="qualified">
    <xs:element name="document">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="rX" minOccurs="1" maxOccurs="unbounded">
                    <xs:complexType>
                        <xs:simpleContent>
                            <xs:extension base="xs:string">
                                <xs:attribute name="style" type="xs:string" />
                            </xs:extension>
                        </xs:simpleContent>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
 </xs:schema>

...其中第9行的“rX”表示需要表达“ r 开头并以X结尾的名称” 。

我宁愿避免自己修复生成代码,所以我想先看看是否可以编写合适的XML Schema。提前感谢大家。

3 个答案:

答案 0 :(得分:6)

XSD要求按字面指定元素名称;我认为你想到的那种宣言不受支持。

正如您所描述的那样(以r开头并以X结尾的名称,这是一个整数),您要编写的声明将在模式中生成无限数量的元素组件;我所知道的唯一支持这种事情的语法形式是由Aard van Wijngaarden为Algol 68开发的两级语法。

因此,在短期内,您最好的选择似乎是更改生成代码,或者为您所需的声明创建自己的符号,并从中生成合法的XSD架构文档。

答案 1 :(得分:4)

在XSD 1.1中,您可以使用xs:any来允许具有任何名称的元素,然后使用断言将名称限制为与正则表达式匹配的名称:

    <xs:complexType>
        <xs:sequence>
            <xs:any minOccurs="1" maxOccurs="unbounded"/>
        </xs:sequence>
        <xs:assertion test="every $x in * 
                            satisfies matches(local-name($x), '[Rr][0-9]+')"/>
    </xs:complexType> 

XSD 1.1目前在Xerces(beta)和Saxon(9.4)中实现。

答案 2 :(得分:0)

我不太熟悉XSD文件的RegEx功能,但表达式本身非常简单。

这将捕获“rX”行号。

<([Rr][0-9]{1,})>

如果你不能使用捕获组,你可以简单地使用它。

[Rr][0-9]{1,}