如何为带格式文本添加长度限制并进行XSD验证?
问题描述
我无法创建满足以下全部需求的XSD文件来验证comment元素:
comment元素可包含文本及可选子元素<b>、<i>、<ul>- 子元素支持嵌套且可多次出现
comment的所有文本内容总长度需限制为60
我已经完成了前两项要求,但不知道如何添加长度限制。以下是我当前的XSD代码及XML示例:
当前XSD代码
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"> <xs:element name="Test"> <xs:complexType> <xs:sequence> <xs:element name="comment" type="FormattedText" minOccurs="0" /> </xs:sequence> </xs:complexType> </xs:element> <xs:complexType name="FormattedText" mixed="true"> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element ref="b" minOccurs="0" /> <xs:element ref="i" minOccurs="0" /> <xs:element ref="ul" minOccurs="0" /> </xs:choice> </xs:complexType> <xs:complexType name="ULType"> <xs:sequence> <xs:element name="li" minOccurs="1" maxOccurs="unbounded"> <xs:complexType mixed="true"> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element ref="b" minOccurs="0" /> <xs:element ref="i" minOccurs="0" /> <xs:element ref="ul" minOccurs="0" /> </xs:choice> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> <xs:element name="b" type="FormattedText" /> <xs:element name="i" type="FormattedText" /> <xs:element name="ul" type="ULType" /> </xs:schema>
XML示例
<?xml version="1.0" encoding="UTF-8"?> <Test> <comment> Abstellorte: <ul> <li>Hinter <b>To<i>r</i></b></li> <li>Am <i>Fenster</i></li> </ul> </comment> </Test>
解决方案
XSD 1.0无法直接限制混合内容(含文本和嵌套元素)的总文本长度,需要使用XSD 1.1的xs:assert断言特性实现。具体修改如下:
- 启用XSD 1.1支持:在schema根元素添加版本控制命名空间和版本声明
- 给
comment元素添加断言,计算所有层级文本节点的长度总和不超过60
修改后的完整XSD代码:
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" vc:minVersion="1.1" elementFormDefault="qualified"> <xs:element name="Test"> <xs:complexType> <xs:sequence> <xs:element name="comment" minOccurs="0"> <xs:complexType> <xs:complexContent> <xs:extension base="FormattedText"> <!-- 断言:所有文本节点长度总和 ≤60 --> <xs:assert test="sum(//text()/string-length(.)) le 60"/> </xs:extension> </xs:complexContent> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> <xs:complexType name="FormattedText" mixed="true"> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element ref="b" minOccurs="0" /> <xs:element ref="i" minOccurs="0" /> <xs:element ref="ul" minOccurs="0" /> </xs:choice> </xs:complexType> <xs:complexType name="ULType"> <xs:sequence> <xs:element name="li" minOccurs="1" maxOccurs="unbounded"> <xs:complexType mixed="true"> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element ref="b" minOccurs="0" /> <xs:element ref="i" minOccurs="0" /> <xs:element ref="ul" minOccurs="0" /> </xs:choice> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> <xs:element name="b" type="FormattedText" /> <xs:element name="i" type="FormattedText" /> <xs:element name="ul" type="ULType" /> </xs:schema>
补充说明
- 若需要忽略空白字符(如换行、缩进空格)的长度计算,可将断言改为
sum(//text()/string-length(normalize-space(.))) le 60 - 需使用支持XSD 1.1的验证工具(如Saxon、Xerces 2.11+)进行验证
内容的提问来源于stack exchange,提问作者Andreas
相关产品推荐
相关产品推荐

