代码之家  ›  专栏  ›  技术社区  ›  MeCe

用php解析html添加类名

  •  0
  • MeCe  · 技术社区  · 6 年前

    我正在尝试用php把类名添加到我的html输出中。

    输入:

    <div class="clsA">
      <div>
        <div class="clsB">
          Content (can be anything including clsA, clsB etc.)
        </div>
      </div>
    </div>
    

    <div class="clsC">
      <div class="clsB">
          Content (can be anything including clsC, clsB etc.)
      </div>
    </div>
    

    我希望输出为

    <div class="clsA myClass">
      <div>
        <div class="clsB clsInner">
          Content (can be anything including clsA, clsB etc.)
        </div>
      </div>
    </div>
    
    <div class="clsC myClass">
      <div class="clsB clsInner">
          Content (can be anything including clsC, clsB etc.)
      </div>
    </div>
    

    对于根类,我想插入一个类名,对于具有指定类名的第二个div,我想添加另一个类名。但如果不使用第三方库,我就无法找到添加它们的方法。

    基本上是伪代码

    - Add myClass to the root element
    - Add clsInner to the first child element of the root with class name clsB.
    

    注意:我不能用“clsb clsinner”替换clsb,因为在内容中还有其他带有clsb的类。

    3 回复  |  直到 6 年前
        1
  •  2
  •   Greg    6 年前

    对php还不太熟悉,但这行吗?

    $dom = new DOMDocument;
    $dom->loadHTML($html);
    $divs = $dom->getElementsByTagName('div');
    foreach ($divs as $div) {
            $div->setAttribute('class', $div->getAttribute('class').' myclass');
    }
    $html = $dom->saveHTML();
    
        2
  •  1
  •   stckvrw    6 年前

    我知道,要按类获取元素 DOMDocument ,我们还需要使用 DOMXpath() 是的。

    所以你可以试试这个:

    <?php
    $input = '<div class="clsA">
      <div>
        <div class="clsB">
          Content (can be anything including clsA, clsB etc.)
        </div>
      </div>
    </div>';
    
    $dom = new DOMDocument;
    libxml_use_internal_errors(true);
    $dom->loadHTML($input);
    libxml_use_internal_errors(false);
    
    $xpath = new DOMXpath($dom);
    foreach($xpath->evaluate('//div[contains(@class, "clsA")]') as $clsA) {
        $clsA->setAttribute('class',$clsA->getAttribute('class').' myClass');
    }
    foreach($xpath->evaluate('//div[contains(@class, "clsB")]') as $clsB) {
        $clsB->setAttribute('class',$clsB->getAttribute('class').' clsInner');
    }
    
    echo $dom->saveXML($dom);
    ?>
    
        3
  •  0
  •   Professor Abronsius    6 年前

    假设我已经正确理解了,并且您希望在以某种方式生成内容之后,但是在客户机看到它之前,您可以使用 output buffering 我是说, DOMDocument DOMXPath 在内容最终呈现之前,随意修改内容。要查看下面代码的结果,运行页面时需要查看页面的源代码(如果按原样运行)

    <?php
    
        $outerClassName='myClass';
        $innerClassName='clsInner';
    
        $attrib='class';
    
        ob_start();
    ?>
    
    <html>
        <head>
            <title>Manipulating the output</title>
        </head>
        <body>
            <div class="clsA">
              <div>
                <div class="clsB">
                  Content (can be anything including clsA, clsB etc.)
                </div>
              </div>
            </div>
    
            <div class="clsC">
              <div class="clsB">
                  Content (can be anything including clsC, clsB etc.)
              </div>
            </div>
        </body>
    </html>
    <?php
        $dom=new DOMDocument;
        $dom->loadHTML( ob_get_contents() );
        $xp=new DOMXPath( $dom );
        $col = $xp->query( '//div' );
    
    
    
        if( $col->length > 0 ){
            foreach( $col as $node ){
    
                if( !stristr( $node->getAttribute( $attrib ), $outerClassName ) ) {
                    $children=$xp->query( 'div', $node );
    
                    if( $children->length > 0 ){
                        if( $node->hasAttribute( $attrib ) ) $node->setAttribute( $attrib, trim( $node->getAttribute( $attrib ) . ' ' . $outerClassName ) );
                    } else {
                        if( $node->hasAttribute( $attrib ) ) $node->setAttribute( $attrib, trim( $node->getAttribute( $attrib ) . ' ' . $innerClassName ) );
                    }
                }
            }
            ob_clean();
            echo $dom->saveHTML();
        }
    
    
        $dom = $xp = $col = $children = null;
        ob_end_flush();
    ?>