PHP 和 RegEx:在 XML 标记之间获取原始数据,即使整个 XML 似乎无效
PHP & RegEx: Get raw data between XML tags, even if whole XML seems to be invalid
这个问题以前似乎经常被问到,但我发现没有有效的数据解决方案,它很长并且包含特殊的字符,如"<"或"{"或......等等。
我正在服务器上向PHP提交一些巨大的XML数据,如下所示:
<root><id>1</id><text>Here is a very long text with
line breaks, white-spaces and many very unsual charchaters, e.g. < % & }
the text can be more then 5000 characters long
</text></root>
在服务器端,我正在尝试获取文本标签之间的"原始数据"。"文本标签"内的原始数据可以包括任何您可以成像的内容:空格、换行符、奇怪的字符。我提交的是源代码和文本,由CKEditor和代码语法突出显示器格式化。
我通读了这篇文章,基本上每个人都说"使用 XML 解析器",就像 domDocument 不使用正则表达式一样。
例如,首先,我尝试了几个正则表达式语句。这不是我唯一尝试过的方法。当数据连接括号且数据太长时,它将失败:
//#<text[^>]*>['s'S]*?</text>#
$regex = "#<".$element_name."[^>]*>['s'S]*?</".$element_name.">#";
$found = preg_match($regex, $xml, $matches);
if ($found != false)
{
$result = $matches[0];
return $result;
}
其次,我尝试了这个,如果标签内的数据不太奇怪,它可以工作。我认为解析器不喜欢括号"<"并认为 xml 无效。
function getTextBetweenTags($tag, $html, $strict=0)
{
/*** a new dom object ***/
$dom = new domDocument;
/*** load the html into the object ***/
if($strict==0)
{
$dom->loadXML($html);
}
else
{
$dom->loadHTML($html);
}
/*** discard white space ***/
$dom->preserveWhiteSpace = false;
/*** the tag by its tag name ***/
$content = $dom->getElementsByTagname($tag);
/*** the array to return ***/
//$out = array();
foreach ($content as $item)
{
/*** add node value to the out array ***/
//$out[] = $item->nodeValue;
/*** return only the first found element value ***/
return $item->nodeValue;
}
/*** return empty string if nothing found ***/
return "";
}
所以我的问题是:
如果我确切地知道,数据中只有一个开始和结束的"文本"标签,那么使用 PHP 读取原始数据的最佳方法是什么?
如果有人给我一个有效的正则表达式或代码片段,那就太好了。
对不起,我的英语中等。
===对答案的回应===对答案的回应===对答案的回应===
好的,BogdanM和Steven的答案都有效,但我最喜欢的答案来自BogdanM。
我做了什么。 要使它工作:
- 我在客户端站点上创建自己的 XML,现在使用 CDATA 告诉解析器数据开始和结束的位置
- 在服务器端,我使用SimpleXML来解析数据。使用 CDATA,解析它就没有问题了。无论数据多么"奇怪"。
- 我消除了一个常见的"菜鸟错误",使用HTTP-GET发送大数据。我现在只是使用HTTP-POST来没有限制
再次感谢您的帮助。
你也在生成XML吗?因为如果是,则应将文本数据放在 CDATA 之间。然后用 simplexml 或您选择的一些解析器加载您的 xml,并获取文本标记内容。确保你没有 UTF-8 字符,或者一些在 XML 中根本不允许的字符:http://www.w3.org/TR/2000/REC-xml-20001006#NT-Char
否则,您可以这样做:
preg_match('#<text>(.+?)</text>#is', $xml, $matches);
echo $matches[1]; // your data between <text> and </text>
首先,您原始的正则表达式模式没问题,应该可以正常工作:
#<".$item_name."[^>]*>(['s'S]*?)</".$item_name.">#
但是,您可以更改它以使其更具可读性/功能等......
可能性
正则表达式 1
#<text>(.*)</text>#is
只需捕获text
标签之间的所有内容。使用修饰符i
允许TEXT
和text
标记和s
使.
与新行匹配。
正则表达式 2
#<text.*?>(.*)</text>#is
您的原始正则表达式意味着您希望在开始text
标签中收到额外的字符。开始标签中的.*?
允许这样做 - ?
使其在第一个>
停止。
正则表达式 3
#<(text).*?>(.*)</'1>#is
由于开始和结束标签名称相同(即 text
),您可以在开始标记周围放置括号以使其成为捕获组,只需在结束标记中引用 '1
- 因为它是第一个捕获组。
这意味着拼写错误的机会少了一次!
正则表达式 4
#<('.$item_name.').*?>(.*)</'1>#is
使其更具活力。您可以将单词 text
替换为变量(根据您的原始变量)。将其与捕获组混合并像在正则表达式 3 中一样引用,您只需插入一次变量即可获得更清晰、更易读的代码。
比较与原版
#<('.$item_name.').*?>(.*)</'1>#is
#<".$item_name."[^>]*>(['s'S]*?)</".$item_name.">#
工作示例
使用上面的正则表达式 4
$string = "
<root><id>1</id><text>Here is a very long text with
line breaks, white-spaces and many very unsual charchaters, e.g. < % & }
the text can be more then 5000 characters long
</text></root>";
preg_match('#<('.$item_name.').*?>(.*)</'1>#is', $string, $matches);
var_dump($matches);
/**
Output:
array(3) {
[0]=>
string(167) "<text>Here is a very long text with
line breaks, white-spaces and many very unsual charchaters, e.g. < % & }
the text can be more then 5000 characters long
</text>"
[1]=>
string(4) "text"
[2]=>
string(154) "Here is a very long text with
line breaks, white-spaces and many very unsual charchaters, e.g. < % & }
the text can be more then 5000 characters long
"
}
*/
注意:如果您无法获得上述工作示例...工作...那么,您能否提供(通过编辑您的问题或链接)一个不起作用的示例案例?
- 我应该如何从xml文件构建一个javascript页面
- 如果我在javascript中输入无效的电子邮件或空白,如何显示特定的文本框边框红色
- 将XML转换为普通的旧JavaScript对象
- jquery代码在Mozilla中有效,但在其他浏览器上无效
- jQuery AJAX write to XML
- 如何将childNodes用于XML文档
- Javascript”;无效的调用对象“;xml错误
- 未捕获的语法错误:无法在“元素”上设置“innerHTML”属性:提供的标记是无效的 XML
- 无效的 XML 格式 - 如何避免这种情况
- PHP 和 RegEx:在 XML 标记之间获取原始数据,即使整个 XML 似乎无效
- ajaForm 在 responseXML 中返回无效的 XML
- 无效的调用对象 IE 11 长度的 XML 数组 (getElementsByTagName)
- JQuery - Parsexml:一个页面上的有效xml,另一个页面上无效的xml,两个页面上的相同xml
- 错误:无效XML:jquery或将多个根转换为多个变量
- 如何获取XML文件中节点的值.代码无效
- 如何使用jQuery在变量中查找无效的未闭合XML标记
- jqGrid卡在加载…因为无效的XML
- 如何从JavaScript字符串中剥离无效的XML 1.0字符
- 在使用 XMLSerializer() 序列化 XML 之前从 XML 中删除无效字符
- parseXML在Google Apps Script中返回无效的XML