从非XML文档中解析XML

问题描述 投票:2回答:4

在xml / non-xml文件中可能存在一些我需要用其他字符串解析和替换的XML Block .. Scenario就是这样的..

Some Text
<cnt:use name="abc" call="xyz">
   <cnt:param name="x" value="2" />
</cnt:use>
Some Text

无法保证文档是正确的XML文档。 (可能存在一些未公开的标签。或者愚蠢的人在键入HTML时可能犯的其他一些常见错误)。所以我不能使用SAX或DOM。我甚至无法将它传递给XSLT(我是对的吗?)。那么什么是从非xml文档中提取<cnt:*>部分的最佳方法。并阅读它然后用别的东西替换。

php xml design-patterns xml-parsing
4个回答
2
投票

我甚至无法将它传递给XSLT(我是对的吗?)。

对。 XSLT在XML Infoset上运行,它是解析树(XML文档)的表示。而且这个文本通常不能解析为XML。

在XSLT 2.0中有一个函数parse-text()可以读取任何文本,但是必须解析这个文本,直到XSLT 3.0到达,才会有模糊地提醒这种解析的函数 - 当它们存在时,它们会失败,因为text不是格式良好的XML。

从非格式良好的XML中提取XML的和平的整个问题是模糊的,没有明确定义。例如,如果缺少结束标记,您如何确定插入标记的确切位置?


1
投票

嗯。问题是我要在PHP中实现它:(。超级悲伤..所以从Mads Hansen的答案中提到TagSoup的想法。我在PHP 5.3上制作了一个Mini SAX框架.https://github.com/neel/SuSAX/blob/master/sax.php

我保持它更像SAX。同时我也跟踪标签嵌套。并保持一个解析树。我保留了一个setNsFocus()方法,只指定要遵循的标签。

<?php
error_reporting(255);
ini_set('display_errors','On');
header('Content-Type: text/plain');
class MyParser extends \SuSAX\AbstractParser{
    public function open($tag){
        echo ">> open ".$tag->ns().':'.$tag->name().'/'.$this->indentation().($this->parent() ? $this->parent()->name() : '')."\n";
        return "OO";
    }
    public function close($tag){
        echo ">> close ".$tag->ns().':'.$tag->name().'/'.$this->indentation()."\n";
    }
    public function standalone($tag){
        echo ">> standalone ".$tag->ns().':'.$tag->name().'/'.$this->indentation()."\n";
    }
    }
$text = <<<TEXT
Hallo <b>W<html:i>o</html:i>rld</b>
<cnt:tag x="2" y="1">
<cnt:taga x="2" y="1"></cnt:taga>
</cnt:tag>
I am Here
TEXT;
$parser = new \SuSAX\Parser(new MyParser);
$parser->setNsFocus('cnt');
$parser->setText($text);
$text_ = $parser->parse();
var_dump($text_);
?>

0
投票

TagSoup - Just Keep On Truckin'

您可以使用TagSoup来确保所有文档格式正确。

...一个用Java编写的兼容SAX的解析器,它不是解析格式良好或有效的XML,而是解析在野外发现的HTML:糟糕,讨厌和野蛮,尽管通常很短。

TagSoup专为那些必须使用某种理性应用程序设计来处理这些东西的人而设计。

通过提供SAX接口,它允许将标准XML工具应用于最差的HTML。 TagSoup还包括一个命令行处理器,它可以读取HTML文件并生成干净的HTML或格式良好的XML,它与XHTML非常接近。

如果您使用Saxon,you can make TagSoup your parser by adding the following option

...在确保TagSoup位于Java类路径上之后,您可以使用标准的Saxon -x org.ccil.cowan.tagsoup.Parser选项。

还有,Taggle, a TagSoup in C++, available now


0
投票

实际上,您可以尝试使用DOM::loadHTML,因为该方法接受非格式化的标记。

http://php.net/domdocument.loadhtml

© www.soinside.com 2019 - 2024. All rights reserved.