2

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

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

等等。我知道,这不是最好的设计——如果行号是属性会更好,但这就是我必须使用的。它代表了问题所在的行号。有没有办法编写一个模式,让我为元素名称指定一个正则表达式(或类似的) ?我希望 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。提前感谢大家。

4

3 回答 3

6

XSD requires that element names be specified literally; the kind of declaration I think you have in mind is not supported.

As you have described it (a name starting with r and ending with X, which is an integer), the declaration you would like to write would produce an infinite number of element components in the schema; the only grammatical formalism I know that supports this kind of thing is the two-level grammar developed by Aard van Wijngaarden for Algol 68.

So in the short run, your best options appear to be either to change the generating code, or to invent your own notation for your desired declaration and generate a legal XSD schema document from it.

于 2012-12-18T16:15:44.360 回答
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) 中实现。

于 2012-12-19T08:35:34.660 回答
0

我对 XSD 文件的 RegEx 功能并不十分熟悉,但表达式本身相当简单。

这将捕获“rX”行号。

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

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

[Rr][0-9]{1,}
于 2012-12-18T15:06:44.410 回答