欢迎光临
我们一直在努力

掌握DTD验证:XML结构定义全解析

DTD 验证的基本概念

DTD(Document Type Definition)是一种用于定义XML文档结构的规范,通过DTD可以验证XML文档是否符合预定义的规则。DTD验证的核心是确保XML文档的元素、属性、实体等符合预期的结构和约束。

DTD 的基本语法

DTD可以内嵌在XML文档中,也可以作为外部文件引用。以下是内嵌DTD的示例:

<!DOCTYPE bookstore [
<!ELEMENT bookstore (book+)>
<!ELEMENT book (title, author, price)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT author (#PCDATA)>
<!ELEMENT price (#PCDATA)>
<!ATTLIST book category CDATA #REQUIRED>
]>
<bookstore>
<book category="fiction">
<title>The Great Gatsby</title>
<author>F. Scott Fitzgerald</author>
<price>10.99</price>
</book>
</bookstore>

外部DTD文件的引用

将DTD定义保存为外部文件(如bookstore.dtd),然后在XML中引用:

<!DOCTYPE bookstore SYSTEM "bookstore.dtd">
<bookstore>
<book category="fiction">
<title>The Great Gatsby</title>
<author>F. Scott Fitzgerald</author>
<price>10.99</price>
</book>
</bookstore>

bookstore.dtd文件内容:

<!ELEMENT bookstore (book+)>
<!ELEMENT book (title, author, price)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT author (#PCDATA)>
<!ELEMENT price (#PCDATA)>
<!ATTLIST book category CDATA #REQUIRED>

DTD 元素定义

DTD通过<!ELEMENT>定义元素的结构。以下是一些常见的元素定义方式:

  • 文本内容元素:

    <!ELEMENT title (#PCDATA)>

  • 子元素序列:

    <!ELEMENT book (title, author, price)>

  • 选择关系(或逻辑):

    <!ELEMENT book (title | author | price)>

  • 重复次数控制:

    • +:至少一次
    • *:零次或多次
    • ?:零次或一次

    <!ELEMENT bookstore (book+)>

  • DTD 属性定义

    通过<!ATTLIST>定义元素的属性,语法如下:

    <!ATTLIST element_name attribute_name attribute_type default_value>

    示例:

    <!ATTLIST book category CDATA #REQUIRED>
    <!ATTLIST book lang CDATA #IMPLIED>
    <!ATTLIST book edition CDATA "1st">

    属性类型说明:

    • CDATA:字符数据
    • ID:唯一标识符
    • IDREF:引用其他元素的ID
    • ENUMERATED:枚举值(如(a|b|c))

    DTD 实体定义

    实体用于定义可重用的内容,分为内部实体和外部实体。

  • 内部实体:

    <!ENTITY publisher "O'Reilly Media">

  • 外部实体:

    <!ENTITY copyright SYSTEM "copyright.txt">

  • 在XML中使用实体:

    <book>
    <title>Learning XML</title>
    <publisher>&publisher;</publisher>
    <rights>©right;</rights>
    </book>

    使用编程语言验证DTD

    以下是使用Python和Java验证XML文档是否符合DTD的示例。

    Python示例

    使用lxml库验证DTD:

    from lxml import etree

    xml = """
    <!DOCTYPE bookstore [
    <!ELEMENT bookstore (book+)>
    <!ELEMENT book (title, author, price)>
    <!ELEMENT title (#PCDATA)>
    <!ELEMENT author (#PCDATA)>
    <!ELEMENT price (#PCDATA)>
    <!ATTLIST book category CDATA #REQUIRED>
    ]>
    <bookstore>
    <book category="fiction">
    <title>The Great Gatsby</title>
    <author>F. Scott Fitzgerald</author>
    <price>10.99</price>
    </book>
    </bookstore>
    """

    try:
    parser = etree.XMLParser(dtd_validation=True)
    etree.fromstring(xml, parser)
    print("XML is valid against DTD.")
    except etree.XMLSyntaxError as e:
    print(f"Validation error: {e}")

    Java示例

    使用javax.xml.validation验证DTD:

    import javax.xml.XMLConstants;
    import javax.xml.transform.stream.StreamSource;
    import javax.xml.validation.Schema;
    import javax.xml.validation.SchemaFactory;
    import javax.xml.validation.Validator;
    import org.xml.sax.SAXException;
    import java.io.IOException;
    import java.io.StringReader;

    public class DTDValidator {
    public static void main(String[] args) {
    String xml = """
    <!DOCTYPE bookstore [
    <!ELEMENT bookstore (book+)>
    <!ELEMENT book (title, author, price)>
    <!ELEMENT title (#PCDATA)>
    <!ELEMENT author (#PCDATA)>
    <!ELEMENT price (#PCDATA)>
    <!ATTLIST book category CDATA #REQUIRED>
    ]>
    <bookstore>
    <book category="fiction">
    <title>The Great Gatsby</title>
    <author>F. Scott Fitzgerald</author>
    <price>10.99</price>
    </book>
    </bookstore>
    """;

    try {
    SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
    Schema schema = factory.newSchema(new StreamSource(new StringReader(xml)));
    Validator validator = schema.newValidator();
    validator.validate(new StreamSource(new StringReader(xml)));
    System.out.println("XML is valid against DTD.");
    } catch (SAXException | IOException e) {
    System.out.println("Validation error: " + e.getMessage());
    }
    }
    }

    DTD 的局限性

    尽管DTD是XML验证的基础工具,但它存在以下局限性:

    • 不支持数据类型(如整数、日期)。
    • 缺乏命名空间支持。
    • 语法较为简单,无法定义复杂的约束。

    对于更复杂的验证需求,可以考虑使用XML Schema(XSD)或RelaxNG。

    赞(0)
    未经允许不得转载:171主机测评 » 掌握DTD验证:XML结构定义全解析
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址