草庐IT

xml - DTD与XSD定义的XML语言范围

coder 2024-06-27 原文

下列命题成立吗:
对于每个dtd,都有一个xsd定义完全相同的语言,而对于每个xsd,都有一个dtd定义完全相同的语言。或者换一种说法:由任何dtd定义的语言集合正是由任何xsd定义的语言集合?
稍微扩展一下这个问题:XML文档基本上是一个大字符串。语言是字符串的集合。例如,所有mathml文档的(无限)集合是一种语言,所有rss文档的集合也是如此等等。mathml(rss,…)也是所有xml文档(无限)集的一个适当子集。您可以使用dtd或xsd来定义这样的xml子集。
现在,每个DTD都定义了一种语言。但是如果你考虑所有可能的DTD,你会得到一组语言。我的问题是,这个集合是否与您从所有可能的xsd中得到的集合完全相同?如果是这样,那么dtd和xsd是等价的,因为两者定义的xml语言的范围是相等的。
为什么这个问题很重要?如果dtd和xsd都是等价的,那么可以编写一个以dtd为输入并提供等价xsd的程序,而另一个程序则相反。我知道有很多程序声称可以做到这一点,但我怀疑这是否真的可能。

最佳答案

一个有趣的问题;问得好!
答案是“不”,在两个方向上。
这是一个在xsd中没有等价物的dtd:

<!ELEMENT e (#PCDATA | e)* >
<!ENTITY egbdf "Every good boy deserves favor.">

此DTD接受的字符序列集包括<e/><e>&egbdf;</e>,但不包括<e>&beadgcf;</e>
由于xsd验证操作的信息集中的实体都已展开,因此没有xsd模式可以区分第三种情况和第二种情况。
DTD可以表示在XSD中不可表示的约束的第二个领域涉及表示法类型。我不举一个例子,细节太复杂了,我不查就记不住了,而且没有足够的兴趣让我想这么做。
第三个方面:DTD以同样的方式处理命名空间属性(也称为命名空间声明)和常规属性;因此DTD可以约束文档中命名空间声明的外观。xsd架构不能。这同样适用于xsi命名空间中的属性。
如果我们忽略所有这些问题,并且只针对不包含对预定义实体ltgt等以外的命名实体的引用的字符序列来制定问题,那么答案就会改变:对于每个不涉及符号声明的dtd,都有一个xsd模式。它在实体扩展后接受完全相同的文档集,并以忽略xsi命名空间中的命名空间属性和属性的方式定义“相同”。
在另一个方面,不同的领域包括:
xsd支持命名空间:以下xsd架构接受指定目标命名空间中元素e的任何实例,而不管文档实例中绑定到该命名空间的前缀是什么。
<xs:schema xmlns:xs="..." targetNamespace="http://example.com/nss/24397">
  <xs:element name="e" type="xs:string"/>
</xs:schema>

没有DTD可以成功地接受给定命名空间中的所有且仅接受e元素。
xsd有更丰富的数据类型集,可以使用数据类型来约束元素和属性。以下xsd架构没有等效的dtd:
<xs:schema xmlns:xs="...">
  <xs:element name="e" type="xs:integer"/>
</xs:schema>

此架构接受文档<e>42</e>,但不接受文档<e>42d Street</e>。DTD不能做出这种区分,因为DTD没有约束PCData内容的机制。最接近的dtd是<!ELEMENT e (#PCDATA)>,它接受两个示例文档。
xsd的xsi:type属性允许在文档中修改内容模型。以下架构文档描述的xsd架构没有等效的dtd:
<xs:schema xmlns:xs="...">
  <xs:complexType name="e">
    <xs:sequence>
      <xs:element ref="e" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="e2">
    <xs:sequence>
      <xs:element ref="e" minOccurs="2" maxOccurs="2"/>
    </xs:sequence>
  </xs:complexType>

  <xs:element name="e" type="e"/>
</xs:schema>

此架构接受文档<e xmlns:xsi="..." xsi:type="e2"><e/><e/></e>并拒绝文档<e xmlns:xsi="..." xsi:type="e2"><e/><e/><e/></e>。DTD没有机制使内容模型依赖于文档实例中给定的属性值。
xsd通配符允许在指定元素的子元素中包含任意格式良好的xml;与dtd最接近的是使用<!ELEMENT e ANY>格式的元素声明,这是不同的,因为它要求对所有实际出现的元素进行声明。
xsd 1.1提供断言和条件类型分配,在dtd中没有类比。
也许还有其他方法可以使xsd的表达能力超过dtd,但我认为这一点已经得到了充分的说明。
我认为一个公平的总结是:xsd可以表示dtd可以表示的所有内容,除了实体声明和特殊情况(如名称空间声明和xsi:*属性),因为xsd被设计成能够这样做。因此,在将dtd转换为xsd模式文档时,信息的丢失是相对温和的,也很容易理解,而且大多数词汇表设计者认为dtd是不重要的人工制品。
xsd可以比dtd表达更多的内容,同样因为xsd就是这样设计的。在一般情况下,从xsd到dtd的转换必然涉及到信息的丢失(接受的文档集可能需要更大、更小或是重叠的集合)。对于如何管理信息丢失,可以做出不同的选择,这就产生了一个问题:“如何最好地将xsd转换为dtd形式?”一定的理论兴趣。(然而,很少有人在实践中发现这是一个有趣的问题。)
所有这些都集中在文档作为字符序列,语言作为文档集,模式语言作为语言的生成器上。架构中存在的可维护性和信息的问题(例如,文档模型中类层次结构的处理)没有转化为文档集扩展的差异,这是不考虑的。

关于xml - DTD与XSD定义的XML语言范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19683429/

有关xml - DTD与XSD定义的XML语言范围的更多相关文章

  1. ruby - Facter::Util::Uptime:Module 的未定义方法 get_uptime (NoMethodError) - 2

    我正在尝试设置一个puppet节点,但ruby​​gems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由ruby​​gems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby

  2. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  3. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  4. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  5. ruby-on-rails - form_for 中不在模型中的自定义字段 - 2

    我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢

  6. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

  7. ruby - 触发器 ruby​​ 中 3 点范围运算符和 2 点范围运算符的区别 - 2

    请帮助我理解范围运算符...和..之间的区别,作为Ruby中使用的“触发器”。这是PragmaticProgrammersguidetoRuby中的一个示例:a=(11..20).collect{|i|(i%4==0)..(i%3==0)?i:nil}返回:[nil,12,nil,nil,nil,16,17,18,nil,20]还有:a=(11..20).collect{|i|(i%4==0)...(i%3==0)?i:nil}返回:[nil,12,13,14,15,16,17,18,nil,20] 最佳答案 触发器(又名f/f)是

  8. ruby-on-rails - 相关表上的范围为 "WHERE ... LIKE" - 2

    我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que

  9. ruby - 在 Ruby 中有条件地定义函数 - 2

    我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin

  10. ruby - 当使用::指定模块时,为什么 Ruby 不在更高范围内查找类? - 2

    我刚刚被困在这个问题上一段时间了。以这个基地为例:moduleTopclassTestendmoduleFooendend稍后,我可以通过这样做在Foo中定义扩展Test的类:moduleTopmoduleFooclassSomeTest但是,如果我尝试通过使用::指定模块来最小化缩进:moduleTop::FooclassFailure这失败了:NameError:uninitializedconstantTop::Foo::Test这是一个错误,还是仅仅是Ruby解析变量名的方式的逻辑结果? 最佳答案 Isthisabug,or

随机推荐