【发布时间】:2015-02-10 21:57:21
【问题描述】:
我需要验证“简化”DTD 是否真的是更大 DTD 的子集,即根据“简化”DTD 有效的文档也将始终根据较大(或“主”)DTD 有效。
现在正在编写简化的 DTD - 它是从主 DTD 派生的(如果反过来,可以简单地将较小的 DTD 包含到较大的 DTD 中)。
如何确定简化 DTD 是否源自主 DTD?
【问题讨论】:
我需要验证“简化”DTD 是否真的是更大 DTD 的子集,即根据“简化”DTD 有效的文档也将始终根据较大(或“主”)DTD 有效。
现在正在编写简化的 DTD - 它是从主 DTD 派生的(如果反过来,可以简单地将较小的 DTD 包含到较大的 DTD 中)。
如何确定简化 DTD 是否源自主 DTD?
【问题讨论】:
DTD 实际上只是伪装的上下文无关语法。一个文法 G 表示一组可能的合法字符串,这些字符串组成了该文法所代表的未陈述语言 L(G)。
你问的,等于判断你有没有G1和G2,L(G1)是不是L(G2)的一个子集。我的语言理论越来越生疏了,我不记得这是否是可计算的,但我猜这真的很难,因为你必须证明 G1 中的任意推导总是在 G2 中具有推导。
您也许可以回答 G1 的结构是否可以通过证明 G1 的每个元素与G2,本质上是通过显示每个语法规则 在 G1 中有一个相应的规则在 G2 中删除了元素。您对 DTD 进行差异化的想法似乎是沿着这条线走的,但前提是如果差异很大,您会遇到一般问题而不是更简单的问题。至少您描述问题的方式(G2源自主DTD)我认为您有机会。 diff 的目的是通过找到最小的差异来识别兼容的规则。
如果你有语法规则 g2 = A ;另一个你声称相关的 g1 = A 和 你想检查的, 您首先必须证明 A 在 G1 中派生的字符串标记是超集 在 G2 中派生的记号 A 的字符串。这看起来就像比较两种语言的原始无约束问题;我们现在只是比较两条规则 g1 和 g2 的子语言。
所以现在我认为你必须坚持 g1 可达的每个子规则在结构上与 g2 中的相应子规则兼容,以使其实用。 我认为您可能可以编写一个递归过程来检查这一点。此过程最需要帮助的是您在 LALR 解析器生成器中往往会找到的所有集合运算符(FirstOf、..)。
在另一个方面,我的公司制造了Smart Differencer 工具,它根据语言元素和对这些元素的编辑操作计算语言结构的增量。它由语言定义参数化。 SmartDifference 目前适用于各种传统语言(C、C++、C#、COBOL、Java、PHP、Python ......)。 XML(和 DTD)也是一种语言,我们有一个语言定义,并且我们已经构建了一个实验性的 XML Smart Differencer 工具。它应该可以在 DTD 上正常工作。如果您有进一步的直接兴趣,请离线联系我(参见简历)。
编辑:只是为了笑,我尝试了以下两个 DTD,一个来自另一个:
orderform.xml:
<?xml version='1.0' ?>
<!DOCTYPE orderform [
<!ELEMENT orderform (name,company,address,items) >
<!ELEMENT name ( firstname, lastname )>
<!ELEMENT firstname ( #PCDATA )>
<!ELEMENT lastname ( #PCDATA )>
<!ELEMENT company ( #PCDATA )>
<!ELEMENT address ( street, city, country )>
<!ELEMENT street ( #PCDATA )>
<!ELEMENT city( #PCDATA )>
<!ELEMENT country ( zipcode | nation )>
<!ELEMENT zipcode ( #PCDATA )>
<!ELEMENT nation ( #PCDATA )>
<!ELEMENT items (item)+ >
<!ELEMENT item ( partnumber, quantity, unitprice)>
<!ELEMENT partnumber ( #PCDATA )>
<!ELEMENT quantity ( #PCDATA )>
<!ELEMENT unitprice ( #PCDATA )>
]>
<done/>
和orderform2.xml:
<?xml version='1.0' ?>
<!DOCTYPE orderform [
<!ELEMENT orderform (name,company,location,item) >
<!ELEMENT name ( firstname, lastname )>
<!ELEMENT firstname ( #PCDATA )>
<!ELEMENT lastname ( #PCDATA )>
<!ELEMENT company ( #PCDATA )>
<!ELEMENT location ( street, city, country )>
<!ELEMENT street ( #PCDATA )>
<!ELEMENT city( #PCDATA )>
<!ELEMENT country ( zipcode | nation )>
<!ELEMENT zipcode ( #PCDATA )>
<!ELEMENT nation ( #PCDATA )>
<!ELEMENT item ( partnumber, unitprice)>
<!ELEMENT partnumber ( #PCDATA )>
<!ELEMENT quantity ( #PCDATA )>
<!ELEMENT unitprice ( #PCDATA )>
]>
<done/>
[先看看你是否能自己发现差异:-)
然后运行 XML SmartDifferencer:
C:\DMS\Domains\XML\Analyzers\SmartDifferencer\Source>DMSSmartDifferencer XML -SuppressSourceCodeForRenamings C:\DMS\Domains\XML\Tool
s\DTD2COBOL\orderform.xml C:\DMS\Domains\XML\Tools\DTD2COBOL\orderform2.xml
Copyright (C) 2009 Semantic Designs; All Rights Reserved
XML SmartDifferencer Version 1.1.1
Copyright (C) 2009 Semantic Designs, Inc; All Rights Reserved; SD Confidential
Powered by DMS (R) Software Reengineering Toolkit
*** Unregistered SmartDifferencer Version 1.1
*** Operating with evaluation limits.
*** Parsing file C:/DMS/Domains/XML/Tools/DTD2COBOL/orderform.xml ...
*** Parsing file C:/DMS/Domains/XML/Tools/DTD2COBOL/orderform2.xml ...
*** Creating suffix tree ...
*** Determining maximal pairs ...
*** Sorting maximal pairs ...
*** Determining differences ...
*** Printing edits ...
Rename 4.1-9.44 to 4.1-9.45 with 'address'->'location' and 'items'~>'item'
Delete 15.1-15.25 merging 15.18-15.21 into 4.44-4.47
<<!ELEMENT items (item)+ >
Delete 16.30-16.38 merging 16.30-16.38 into 15.18-15.28 with 'quantity'~>'partnumber'
< quantity,
是的,这就是我为得到派生的所做的。 (符号 N.M 的意思是“第 N 行,第 M 列”)。
【讨论】: