重定义DTD元素:复用OOTB元素并自定义结构的实现难题
解决思路与实现步骤
1. 正确引入外部DTD实体
要复用外部DTD里的<image>``<b>``<i>,同时基于原定义重定义<topic>``<body>``<p>,首先得通过参数实体引入外部DTD的内容。假设外部DTD文件路径为external.dtd,代码示例:
<!-- 引入完整外部DTD,若外部DTD未拆分实体只能用这种方式 --> <!ENTITY % externalDTD SYSTEM "external.dtd"> %externalDTD; <!-- 若外部DTD将元素封装为参数实体,可按需引入特定元素(需外部DTD支持) --> <!ENTITY % imageDef SYSTEM "external.dtd#image"> %imageDef; <!ENTITY % bDef SYSTEM "external.dtd#b"> %bDef; <!ENTITY % iDef SYSTEM "external.dtd#i"> %iDef;
2. 重定义<topic>元素
直接覆盖原定义,限制其子元素仅为<body>:
<!ELEMENT topic (body)> <!-- 复用原<topic>的属性定义(如果外部DTD有属性声明,替换为对应属性实体) --> <!ATTLIST topic %topicAtts;>
3. 重定义<body>元素
指定其子元素为<image>和<p>,可根据需求调整出现顺序与次数(比如(image, p+)表示先<image>后至少一个<p>):
<!ELEMENT body (image, p)> <!-- 复用原<body>的属性定义 --> <!ATTLIST body %bodyAtts;>
4. 重定义<p>元素
定义其内容为PCDATA、<b>、<i>的混合结构:
<!ELEMENT p (#PCDATA | b | i)*> <!-- 复用原<p>的属性定义 --> <!ATTLIST p %pAtts;>
关键注意事项
- 重定义操作必须放在外部DTD引入之后,否则会因找不到原元素声明报错。
- 如果外部DTD中目标元素带有属性,一定要复用原属性实体,避免丢失原有属性约束。
- 若外部DTD未拆分元素实体,只能先引入完整DTD再重定义,此时重定义会完全替换原元素的声明。
完整示例DTD代码
<!-- 引入外部DTD --> <!ENTITY % externalDTD SYSTEM "external.dtd"> %externalDTD; <!-- 重定义topic --> <!ELEMENT topic (body)> <!ATTLIST topic %topicAtts;> <!-- 重定义body --> <!ELEMENT body (image, p)> <!ATTLIST body %bodyAtts;> <!-- 重定义p --> <!ELEMENT p (#PCDATA | b | i)*> <!ATTLIST p %pAtts;>
内容的提问来源于stack exchange,提问作者marc
相关产品推荐
相关产品推荐

