Php 如何从XML中提取某些标记并用SimpleXML替换其他标记
我正在用PHP写我自己的博客,我想能够用Markdown写文章,用HTML显示结果,我还需要用HTML做一些自定义的事情 有一个简单的脚本可以将标记转换为HTML,但是一旦完成,我需要对HTML做一些事情:Php 如何从XML中提取某些标记并用SimpleXML替换其他标记,php,xml,parsing,text,replace,Php,Xml,Parsing,Text,Replace,我正在用PHP写我自己的博客,我想能够用Markdown写文章,用HTML显示结果,我还需要用HTML做一些自定义的事情 有一个简单的脚本可以将标记转换为HTML,但是一旦完成,我需要对HTML做一些事情: 我需要使用htmlentities()函数替换pre标记中的所有HTML符号。(在我的博客中,我发布了包括HTML在内的代码,我只想显示这个HTML,不想在浏览器中解析它) 我需要提取所有的纯文本,这样我就可以在最后创建不包含图像标记或半标记(或pre中的代码片段)的摘录 我认为我已经通过使
$xml = new SimpleXMLElement('<xml>' . $html . '</xml>');
$xml=newsimplexmlement('.$html');
$xml现在看起来像:
<xml>
<p>some random text</p>
<img src='image.jpg'>
<p>some random text</p>
</xml>
一些随机文本
一些随机文本
这将提取所有文本:
foreach($xml->{'p'} as $p){
echo $p . '<hr>';
}
foreach($xml->{'p'}作为$p){
回声$p.“
”;
}
这是可行的,但是我也希望它包括在ul和ol中找到的所有文本(与它们在XML中出现的顺序相同)。我已经搜索了一种方法来循环$XML的所有子元素,但我找不到如何检查元素是p、ul还是ol
我找不到解决问题1的方法,因为我不知道如何替换XML对象中的内容,但保留所有其他内容不变(或者我遗漏了一些非常明显的东西?)经过大量搜索,我无法使用XML解析准确地找到我想要的内容,此外,我还需要一些其他功能。我用正则表达式解决了这个问题,因为所有HTML都是由我生成的 因此,这里提供的解决方案解决了我原来的问题+更多的问题 此函数获取一段内容(字符串)并返回两个字符串:
- md=与pre中带有尖括号的内容更改为其html实体(我写了一篇关于html的博客,但在我的编辑帖子屏幕中,我不希望解析pre中的html)相同
- html=pre之外的所有内容都被标记,pre内的所有htmlchar都被更改为其html实体
- 摘录=文本缩小了近300个字符,没有任何前置标记(或其内容),没有标记语法或html标记
- meta=与160个字符的摘录相同
function prepareContent($content) { // I use this instead of htmlentities for the plain text, this prevents HTML to be parsed inside the edit screen // all HTML is served with htmlentities instead function removeAngleBrackets($str) { $str = str_replace('<','<',$str); $str = str_replace('>','>',$str); return $str; } $segments = preg_split('/(<\/?pre.*?>)/', $content, -1, PREG_SPLIT_DELIM_CAPTURE); // STATE MACHINE // borrowed from: http://stackoverflow.com/questions/1278491/howto-encode-texts-outside-the-pre-pre-tag-with-htmlentities-php#answer-1278575 // this breaks when I nest pre's in pre's (unless I escape the <pre> myself), could be fixed though // $state = 0 if outside of a pre // $state = 1 if inside of a pre $state = 0; $plaintext = ''; $html = ''; $preless = ''; // $html, $plaintext and $preless are all written in here foreach ($segments as &$segment) { if ($state == 0) { if (preg_match('#<pre[^>]*>#i',$segment)) { //this is the pre opening tag $state = 1; $html .= $segment; $plaintext .= $segment; } else { //this is outside the pre tag $plaintext .= $segment; $markdown = Markdown($segment); $html .= $markdown; $preless .= $markdown; } } else if ($state == 1) { if ($segment == '</pre>') { //this is the pre closing tag $state = 0; $html .= $segment; $plaintext .= $segment; } else { //this is inside the pre tag $plaintext .= removeAngleBrackets($segment); // first encode > to > so I can re encode it together with other chars // else we get double encoding like: $amp;gt; $enti = html_entity_decode($segment); $html .= htmlspecialchars($enti, ENT_QUOTES); } } } $arr['html'] = SmartyPants($html); $arr['md'] = $plaintext; // the excerpt & meta // remove all html tags (markdown is already converted to HTML) $tagless = strip_tags($preless); function shrinkText($str, $limit) { $strlen = strlen($str); if($strlen > $limit) { $pos = strpos($str, ' ', $limit); if($strlen > $pos) { $result = substr($str,0,$pos); } } return $result ? $result : $str; } // I need to smartypants the excerpt to $excerpt = shrinkText($tagless, 275) . ' (...)'; $arr['excerpt'] = SmartyPants($excerpt); $arr['meta'] = shrinkText($tagless, 160); return $arr; }
函数prepareContent($content){ //我对纯文本使用它而不是htmlentities,这可以防止在编辑屏幕内解析HTML //所有HTML都使用htmlentities代替 函数RemoveAngle括号($str){ $str=str_替换('',$str); 返回$str; } $segments=preg_split(“/()/”,$content,-1,preg_split_DELIM_CAPTURE); //状态机 //借用自:http://stackoverflow.com/questions/1278491/howto-encode-texts-outside-the-pre-pre-tag-with-htmlentities-php#answer-1278575 //当我将pre的嵌套在pre的中时,这会中断(除非我自己逃脱),但可以修复 //$state=0(如果在预处理程序之外) //$state=1,如果在预处理 $state=0; $plaintext=''; $html=''; $preless=''; //$html、$plaintext和$preless都写在这里 foreach($segments as&$segment){ 如果($state==0){ if(preg#u匹配('#]*>i',$segment)){ //这是开幕前的标签 $state=1; $html.=$segment; $plaintext.=$segment; }否则{ //这在预标记之外 $plaintext.=$segment; $markdown=降价($section); $html.=$markdown; $preless.=$markdown; } }else if($state==1){ 如果($segment=''){ //这是预关闭标签 $state=0; $html.=$segment; $plaintext.=$segment; }否则{ //这在pre标签内 $plaintext.=删除方括号($segment); //首先编码到>,这样我就可以和其他字符一起重新编码 //否则我们会得到双重编码,比如:$amp;gt; $enti=html\u实体\u解码($segment); $html.=htmlspecialchars($enti,ENT_引号); } } } $arr['html']=SmartyPants($html); $arr['md']=$plaintext; //节选与元分析 //删除所有html标记(标记已转换为html) $tagless=带标签($preless); 函数收缩文本($str,$limit){ $strlen=strlen($str); 如果($strlen>$limit){ $pos=STRP($str,,$limit); 如果($strlen>$pos){ $result=substr($str,0,$pos); } } 返回$result?$result:$str; } //我需要把这段摘录发给你 $extract=收缩文本($tagless,275)。“(…)”; $arr['extract']=SmartyPants($extract); $arr['meta']=收缩文本($tagless,160); 返回$arr; }