将HTML转换为XML

我得到了需要以XML格式传送的HTML文件。 我们正在使用这些HTML为应用程序提供内容,但现在我们必须将这些内容作为XML提供。

HTML文件是包含,表,div,图片,p的,b或强标签等。

我GOOGLE了一下,发现了一些应用程序,但我还没有达到目的。

你能build议一种将这些文件内容转换为XML的方法吗?

我成功地使用tidy命令行工具。 在Linux上,我用apt-get install tidy快速安装了它。 然后命令:

tidy -q -asxml source.html >file.xml

给了一个xml文件,我可以用xslt处理器进行处理。 不过,我需要正确设置xhtml1 dtds。

这是他们的主页: html-tidy.org (和遗留的: HTML Tidy )

我确实发现了一种将(甚至是坏的)html转换成格式良好的XML的方法。 我开始基于DOM的loadHTML函数。 然而,在一段时间内发生了几个问题,我优化并添加了补丁,以纠正副作用。

  function tryToXml($dom,$content) { if(!$content) return false; // xml well formed content can be loaded as xml node tree $fragment = $dom->createDocumentFragment(); // wonderfull appendXML to add an XML string directly into the node tree! // aappendxml will fail on a xml declaration so manually skip this when occurred if( substr( $content,0, 5) == '<?xml' ) { $content = substr($content,strpos($content,'>')+1); if( strpos($content,'<') ) { $content = substr($content,strpos($content,'<')); } } // if appendXML is not working then use below htmlToXml() for nasty html correction if(!@$fragment->appendXML( $content )) { return $this->htmlToXml($dom,$content); } return $fragment; } // convert content into xml // dom is only needed to prepare the xml which will be returned function htmlToXml($dom, $content, $needEncoding=false, $bodyOnly=true) { // no xml when html is empty if(!$content) return false; // real content and possibly it needs encoding if( $needEncoding ) { // no need to convert character encoding as loadHTML will respect the content-type (only) $content = '<meta http-equiv="Content-Type" content="text/html;charset='.$this->encoding.'">' . $content; } // return a dom from the content $domInject = new DOMDocument("1.0", "UTF-8"); $domInject->preserveWhiteSpace = false; $domInject->formatOutput = true; // html type try { @$domInject->loadHTML( $content ); } catch(Exception $e){ // do nothing and continue as it's normal that warnings will occur on nasty HTML content } // to check encoding: echo $dom->encoding $this->reworkDom( $domInject ); if( $bodyOnly ) { $fragment = $dom->createDocumentFragment(); // retrieve nodes within /html/body foreach( $domInject->documentElement->childNodes as $elementLevel1 ) { if( $elementLevel1->nodeName == 'body' and $elementLevel1->nodeType == XML_ELEMENT_NODE ) { foreach( $elementLevel1->childNodes as $elementInject ) { $fragment->insertBefore( $dom->importNode($elementInject, true) ); } } } } else { $fragment = $dom->importNode($domInject->documentElement, true); } return $fragment; } protected function reworkDom( $node, $level = 0 ) { // start with the first child node to iterate $nodeChild = $node->firstChild; while ( $nodeChild ) { $nodeNextChild = $nodeChild->nextSibling; switch ( $nodeChild->nodeType ) { case XML_ELEMENT_NODE: // iterate through children element nodes $this->reworkDom( $nodeChild, $level + 1); break; case XML_TEXT_NODE: case XML_CDATA_SECTION_NODE: // do nothing with text, cdata break; case XML_COMMENT_NODE: // ensure comments to remove - sign also follows the w3c guideline $nodeChild->nodeValue = str_replace("-","_",$nodeChild->nodeValue); break; case XML_DOCUMENT_TYPE_NODE: // 10: needs to be removed case XML_PI_NODE: // 7: remove PI $node->removeChild( $nodeChild ); $nodeChild = null; // make null to test later break; case XML_DOCUMENT_NODE: // should not appear as it's always the root, just to be complete // however generate exception! case XML_HTML_DOCUMENT_NODE: // should not appear as it's always the root, just to be complete // however generate exception! default: throw new exception("Engine: reworkDom type not declared [".$nodeChild->nodeType. "]"); } $nodeChild = $nodeNextChild; } ; } 

现在,这也允许添加更多的HTML片段到一个我需要使用自己的XML。 一般来说,它可以这样使用:

  $c='<p>test<font>two</p>'; $dom=new DOMDocument('1.0', 'UTF-8'); $n=$dom->appendChild($dom->createElement('info')); // make a root element if( $valueXml=tryToXml($dom,$c) ) { $n->appendChild($valueXml); } echo '<pre/>'. htmlentities($dom->saveXml($n)). '</pre>'; 

在这个例子中, '<p>test<font>two</p>'很好地在格式良好的XML中输出为' <info><p>test<font>two</font></p></info> ”。 信息根标签被添加,因为它也允许转换不是XML的“ <p>one</p><p>two</p> ”,因为它没有一个根元素。 但是,如果你的html确实有一个根元素,那么可以跳过额外的根<info>标签。

有了这个,我得到了非结构化,甚至损坏的HTML真正好的XML!

我希望这有点清楚,可能有助于其他人使用它。

请记住,HTML和XML是标记语言树中两个不同的概念。 你不能完全用XMLreplaceHTML 。 XML可以被看作是HTML的一种广义forms,但即使这样也是不准确的。 您主要使用HTML来显示数据,使用XML来传输(或存储)数据。

这个链接是有帮助的: 如何阅读HTML为XML?

更多这里 – HTML和XML的区别