2010-11-20 21 views
2

我有成千上万的SGML文档,其中一些格式良好,一些格式不够完善。我需要获取文档中的某些ELEMENTS,但每次我加载并尝试将它们读入XDocument,XMLDocument或甚至是StreamReader时,都会得到各种各样的XMLException错误。解析不完整格式的SGML/XML文档的LOTS和LOTS的策略

像'''是一个意外的标记。“。为什么?因为我有一个DOCTYPE文件,如

<!DOCTYPE RChapter PUBLIC "-//LSC//DTD R Chapter for Authoring//EN" [] > 

我知道“[]”需要内部有效的东西。同样,我不控制文档的创建,但我必须“破解”它们并获取我想要的数据。另一个例子是具有一个“非闭合”元件,例如:

<Caption>Plants, and facilities<hardhyphen><hyphen>Inspection.</Caption> 

这XMLException是“第27行的‘连字符’开始标记不‘标题’线27,位置58的结束标记相匹配。 “很明显,对吗?

但是接下来的问题是,如何在这些文档中实际获得某些ELEMENTS,而不会遇到XMLExceptions。 SAX解析器是否正确?我基本上想打开文档,直接转到我想要的元素(不用担心附近可能形成或不可能形成什么),拉取数据,然后继续。如果我只是忘了为XMLDocument,的XDocument解析,并只是做简单的字符串替换像

str.Replace("<hardhypen><hyphen>", "-") 

,然后尝试将其加载到XML解析器之一。有关战略的任何提示?

+0

您使用哪种语言? – 2010-11-20 04:00:29

+0

我可以使用C#或VB.NET – Robert4Real 2010-11-20 14:24:07

+0

,如果它没有很好地形成,它不是XML,那是你遇到的问题。你想先将你的SGML转换为XML,首先https://github.com/MindTouch/SGMLReader,http://mmalachowski.blogspot.com/2013/08/performance-test-of-c-html-xpath.html – Jodrell 2017-03-09 13:42:26

回答

3

问题是你试图用XML工具解析SGML。他们不一样。如果您想使用XML工具/语言来访问数据,您可能需要在尝试解析它之前将SGML转换为XML。

理想情况下,您要么使用支持SGML的语言/工具(如OmniMark),要么可以处理“XML like”数据(比如第一个答案中的nokogiri?)。

这可能是相当直接的,但在某些方面可能会变得棘手。特别是如果你在谈论多个文档类型(DTD)。 (也没有“格式良好”的SGML这样的东西,是的,元素/等必须正确嵌套,但SGML 有一个DTD。)

这里是SGML和XML之间的一些区别你需要处理。 (您可能不想走这条路线,但无论如何它可能对信息有所帮助。):

  1. DOCTYPE声明

    DOCTYPE声明在你的例子是完全有效的SGML文档类型。 [](内部子集)不必有任何内容。如果你在内部子集中有声明(通常是实体声明),你很可能不得不在XML中保留一个doctype声明。

    XML解析器遇到的问题是您在声明中没有系统标识符。在XML文档类型声明中,如果存在公共标识符,则系统标识符是必需的。在SGML doctype声明中,它不是必需的。底线:除非您需要将XML解析为DTD/Schema或在内部子集中声明,否则请删除doctype声明。如果XML必须有效,那么您至少需要添加一个系统标识符。不要忘记添加<?xml ...?>处理指令。

  2. 元素没有结束标记

    <hardhyphen><hyphen>元素是有效的SGML。 SGML DTD允许您指定标签最小化。这意味着您可以指定是否需要结束标记。 (您也可以开始标记可选的,但是这是疯话。)在XML中,你必须关闭这些元素(如<hardhyphen/><hardhyphen></hardhyphen>

    做的最好的事情是看你的SGML DTD,看看哪些要素有可选的结束标签。标签最小化在元素声明中的元素名称后面指定。 ' - '表示标签是必需的。 'o'(字母'哦')表示标签是可选的。例如,如果看到<!ELEMENT hyphen - o (#PCDATA)>,则表示需要开始标记(-),结束标记是可选的(o)。如果您看到<!ELEMENT hyphen - - (#PCDATA)>,则需要开始标记和结束标记。

    底线:正常关闭所有没有结束标签在SGML

  3. 处理指令

    处理指令(PI)并不具备第二?的时候都喜欢封闭的元素XML的确如此。您需要添加第二个?

    例SGML PI:<?asdf jkl>

    示例XML PI:<?asdf jkl?>

  4. 夹杂物/排除

    你可能不会担心这一点,但在SGML DTD,你可以在指定一个元素声明,该元素内部的任何地方都允许另一个元素(或不允许)。如果您的目标XML需要解析为DTD,这可能会很痛苦; XML DTD不允许包含/排除。

    这是一个包含可能是什么样子:

    <!ELEMENT chapter - - (section)+ +(revst|revend)>

    这是说,revstrevendchapter内的任意位置允许的。如果元素声明有-(revst|revend),这意味着revstrevend而不是允许在chapter内的任何位置。

希望这会有所帮助。

1

是的,使用Nokogiri

在该页面上向下滚动一下,并将“简介”下的代码复制到文件中,如xml-parser.rb。然后,如果您在Mac上(Ruby已安装在Mac上),请从终端运行gem install nokogiri,然后运行该文件:ruby xml-parser.rb

您也可以从终端输入irb,然后输入require 'nokogiri',然后开始实时播放nokogiri api。喜欢互动Ruby。 :)

如果您在Windows上,请尝试此Ruby installer for Windows