1

这是 xml 代码,我将此文本加载为字符串,我需要将其所有嵌套标签和内容替换为 htmlentities..

<?xml version="1.0" encoding="utf-8"?>
<data>
<target><x id="25e02e3e839c-a1e6b03cb682"  pid="NLSheets" name="NLSheets" />Sheets"</target>
<target>"<x id="3510a371bdf8-861b965564ea" pid="NLTable" name="NLTable" />Table"</target>
<target>"<x id="48a1560eaa68-c400c8394f0a"  pid="NLCaption" name="NLCaption" />Caption"</target>
</data>

我为该任务使用了以下 php 代码。

function html_entities($matches) {
  return str_replace($matches[1], htmlentities($matches[1]), $matches[0]);
}

function get_tag( $tagname, $xml ) {
 $pattern = "/<$tagname ?.*>(.*?)<\/$tagname>/"; 
 $content = preg_replace_callback($pattern,  html_entities, $xml);
 return $content;
}

$content = get_tag('target', $str);

echo $content; 

现在问题出在正则表达式上。我使用了正则表达式

正如您在 get_tag 函数中看到的那样。$pattern = "/<$tagname ?.*>(.*?)<\/$tagname>/";这将建立在运行时

/<target ?.*>(.*?)<\/target>

现在我无法解决问题...嵌套标签值未转换为 htmlentities。

请帮忙

4

1 回答 1

1

将行更改为:

$pattern = "/<$tagname ?.*?>(.*?)<\/$tagname>/"; 

您需要一个额外的非贪婪修饰符来防止搜索>开始标签的结束部分 ( ) 走得太远并抓住您的内部内容(因此不能使其可用于括号分组和 htmlentities)。

我们可以通过在末尾使用 's' 修饰符来稍微改进这一点,以允许内容中包含换行符(因为默认情况下点字符不包含换行符)以及防止/在开始标记内出现换行符,并允许任何类型的空格将元素名称与属性分开,并在结束标记的末尾允许空格:

$pattern = "/<$tagname(?:\s[^\/]*?)?>(.*?)<\/$tagname\s*>/s";

并缩短它:

$pattern = "@<$tagname(?:\s[^/]*?)?>(.*?)</$tagname\s*>@s";

为了处理所有这些可能的边缘情况,使用 XML 解析器更安全。例如,这不会捕获:

<target><![CDATA[ </target> ]]></target>
于 2012-04-19T18:19:23.183 回答