如何确定给定的DTD是否是另一个的子集?

时间:2010-03-03 09:42:15

标签: xml diff dtd

我需要验证“简化”DTD实际上是更大DTD的子集,即。根据“简化”DTD有效的文档也将根据较大(或“主”)DTD始终有效。

现在正在编写简化的DTD - 它来自主DTD(反过来,可以简单地将较小的DTD包含在较大的DTD中)。

我如何能够确定简化的DTD是否来自主DTD?

1 个答案:

答案 0 :(得分:2)

DTD实际上只是伪装的无上下文语法。语法G表示包含语法所代表的未说明语言L(G)的可能合法字符串的集合。

你问的是等于确定你是否有G1和G2,L(G1)是否是L(G2)的子集。我的语言理论变得生疏,我不记得这是否可以计算,但我猜这真的很难,因为你必须证明G1中的任意推导总是在G2中有一个推导。

你或许可以通过证明G1的每个元素与每个元素的每个元素相容来回答G1是否以这样的方式构建,即你可以证明L(G1)是L(G2)的子集。 G2,通过显示每个语法规则来实现  在G1中有一个相应的规则,其中元素被删除。您对DTD进行差异化的想法似乎是沿着这条线进行的,条件是如果差异较大,您会遇到一般问题,而不是更简单的问题。至少你对问题的描述方式(G2来自主DTD)我认为你有机会。 差异的目的是通过找出最小差异来识别兼容的规则。

如果你有语法规则g2 = A;和另一个g1 = A你声称是相关的 你想检查, 你首先必须证明在G1中派生的A是超集的字符串标记 在G2中派生的令牌A串。这看起来就像是比较两个语言的原始无约束问题;我们现在只是比较两个规则g1和g2的子语言。

所以现在我认为你必须坚持g1可达到的每个子规则在结构上与g2中的相应子规则兼容,以使其变得实用。 我想你可以写一个递归程序来检查这个。这个过程主要需要帮助的是你倾向于在LALR解析器生成器中找到的所有set运算符(FirstOf,..)。

在另一方面,我的公司制作Smart Differencer工具,根据语言元素和对这些元素的编辑操作来计算语言结构的增量。它由语言定义参数化。 SmartDifference目前适用于各种传统语言(C,C ++,C#,COBOL,Java,PHP,Python,......)。 XML(和DTD)也是一种语言,我们有一个语言定义,我们已经构建了一个实验性的XML Smart Differencer工具。它应该在DTD上运行得很好。如果您有其他直接兴趣,请离线与我联系(参见bio)。

编辑:只是为了笑,我尝试了以下两个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”)。