使用PHP,Xpath和/或DOM更改HTML内容

时间:2010-12-25 21:01:19

标签: php html xslt dom xpath

  

可能重复:
  xPath insert before and after - With DOM and PHP

我需要以正确的方式解析字符串中的HTML代码。

Wordpress会创建一个侧边栏,其结构看起来像这样。

<div class="sidebar-1">
   <ul>
      <li id="archives">
          <h4>Archives</h4>
          <ul>
             <li>a href="">Test1</a></li>
             <li>a href="">Test2</a></li>
          </ul>
      </li>
      <li id="pages">
          <h4>Archives</h4>
          <ul>
             <li>a href="">Test</a></li>
             <li>a href="">Test</a></li>
          </ul>
      </li>
   </ul>

我想创建一个&lt; div class =“content”&gt;在&lt; / h4&gt;之后和一个&lt; / div&gt;在&lt; / li&gt;之前父元素,在“档案”和“页面”的列表部分中。如果添加更多未知列表项,它应该有效。

结果应该是这样的:

<div class="sidebar-1">
   <ul>
      <li id="archives">
          <h4>Archives</h4>
          <div class="content">
             <ul>
                <li>a href="">Test1</a></li>
                <li>a href="">Test2</a></li>
             </ul>
          </div>
      </li>
      <li id="pages">
          <h4>Archives</h4>
          <div class="content">
             <ul>
                <li>a href="">Test</a></li>
                <li>a href="">Test</a></li>
             </ul>
          </div>
      </li>
   </ul>

我尝试制作DOM功能,但我没有弄清楚需要做什么以及如何做。它返回数组中h4-tags内的内容。不是很有帮助。

    function add_sidebar_content($html)
    {
       $dom = new DOMDocument();
       $dom->loadHTML($html);
       $xpath = new DomXPath($dom); 
       $tag = $dom->getElementsByTagName("h4");
       $counter = $tag->length;
       for ($i = 0; $i < $counter; $i++)
       {
          $result = $tag->item($i)->nodeValue;
       }
       return $result;
    }

3 个答案:

答案 0 :(得分:1)

您应该使用钩子来执行此操作,而不是尝试在事后修改内容。我不确定你会使用哪个钩子,但you can find all the hooks available here

答案 1 :(得分:0)

XPath是XML的查询语言,因此无法修改XML文档

为了修改XML文档,需要使用托管XPath的编程语言(如XSLT,C#,JS,PHP等)。

这是一个解决方案,托管语言是XSLT

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="node()|@*" name="identity">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match=
 "li/ul[preceding-sibling::*[1]
         [self::h4 and .='Archives']
       ]">
  <div class="content">
   <xsl:call-template name="identity"/>
  </div>
 </xsl:template>
</xsl:stylesheet>

将此转换应用于提供的XML文档(更正为格式良好):

<div class="sidebar-1">
    <ul>
        <li id="archives">
            <h4>Archives</h4>
            <ul>
                <li>
                    <a href="">Test1</a>
                </li>
                <li>
                    <a href="">Test2</a>
                </li>
            </ul>
        </li>
        <li id="pages">
            <h4>Archives</h4>
            <ul>
                <li>
                    <a href="">Test</a>
                </li>
                <li>
                    <a href="">Test</a>
                </li>
            </ul>
        </li>
    </ul>
</div>

产生了想要的正确结果

<div class="sidebar-1">
   <ul>
      <li id="archives">
         <h4>Archives</h4>
         <div class="content">
            <ul>
               <li>
                  <a href="">Test1</a>
               </li>
               <li>
                  <a href="">Test2</a>
               </li>
            </ul>
         </div>
      </li>
      <li id="pages">
         <h4>Archives</h4>
         <div class="content">
            <ul>
               <li>
                  <a href="">Test</a>
               </li>
               <li>
                  <a href="">Test</a>
               </li>
            </ul>
         </div>
      </li>
   </ul>
</div>

答案 2 :(得分:0)