Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/266.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/29.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何从XML中提取某些标记并用SimpleXML替换其他标记_Php_Xml_Parsing_Text_Replace - Fatal编程技术网

Php 如何从XML中提取某些标记并用SimpleXML替换其他标记

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中的代码片段)的摘录 我认为我已经通过使

我正在用PHP写我自己的博客,我想能够用Markdown写文章,用HTML显示结果,我还需要用HTML做一些自定义的事情

有一个简单的脚本可以将标记转换为HTML,但是一旦完成,我需要对HTML做一些事情:

  • 我需要使用htmlentities()函数替换pre标记中的所有HTML符号。(在我的博客中,我发布了包括HTML在内的代码,我只想显示这个HTML,不想在浏览器中解析它)

  • 我需要提取所有的纯文本,这样我就可以在最后创建不包含图像标记或半标记(或pre中的代码片段)的摘录

  • 我认为我已经通过使用以下代码解决了问题2:

    $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('<','&lt;',$str);
              $str = str_replace('>','&gt;',$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 &gt; 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;
      }
      

    的可能重复-请参阅:还有更多其他问题和答案也涵盖了这一点。我建议您使用搜索。