PHP DOM实现

时间:2014-04-17 09:26:00

标签: php html dom

我有一个转换器,它将doc和docx转换为html,转换器的类文件如下

<?php
    class docxhtml {
        public $connectname;
        public $connectpass;

        public function __construct($format_res, $flname) {
            require_once('config.php');
            // Turn up error reporting
            error_reporting (E_ALL|E_STRICT);

            // Turn off WSDL caching
            ini_set ('soap.wsdl_cache_enabled', 0);

            // Define credentials for LD
            define ('USERNAME', $this->connectname);
            define ('PASSWORD', $this->connectpass);

            // SOAP WSDL endpoint
            define ('ENDPOINT', 'https://api.livedocx.com/2.1/mailmerge.asmx?wsdl');

            // Define timezone

            date_default_timezone_set('Europe/Berlin');

            // Instantiate SOAP object and log into LiveDocx

            $this->soap = new SoapClient(ENDPOINT);

            $this->soap->LogIn(
                array(
                    'username' => USERNAME,
                    'password' => PASSWORD
                )
            );

            // Upload template

            $this->data = file_get_contents('Original/'.$format_res);

            $this->soap->SetLocalTemplate(
                array(
                    'template' => base64_encode($this->data),
                    'format'   => 'docx'
                )
            );

            $this->result = $this->soap->RetrieveDocument(
                array(
                    'format' => 'html'
                )
            );

            $this->data = $this->result->RetrieveDocumentResult;



            file_put_contents('Recode/'.$flname.'.html', base64_decode($this->data));

        }
    }
?>

正如您所看到的,这个类文件将转换后的文件发送到Recode文件夹,然后由前端PHP中的脚本通过保存对话框下载..

现在我需要的指导是..我想将那个结果HTML转换为清理剥离的html,我为其编写了如下代码,效果很好

<?php
$path = 'path to previous html output file from local machine';
$html = file_get_contents($path);
$dom = new DOMDocument();
//$dom->strictErrorChecking = false;
$dom->formatOutput = true;
$dom->loadHTML($html);

$xpath = new DOMXPath($dom);
if (false === ($elements = $xpath->query("//*"))) die('Error');

foreach ($elements as $element) {
    for ($i = $element->attributes->length; --$i >= 0;) {
        $name = $element->attributes->item($i)->name;
        if (('img' === $element->nodeName && 'src' === $name)
            || ('a' === $element->nodeName && 'href' === $name)
        ) {
            continue;
        }

        $element->removeAttribute($name);
    }
}

echo $dom->saveHTML();

?>

现在我想合并这两个..即在第一类文件中将数据存储到recode文件夹之前它应该处理这个dom代码然后将该输出保存到该重新编码文件夹..请指导我

1 个答案:

答案 0 :(得分:0)

试试这个解决方案:

<?php
class docxhtml
{
    /** @var string */
    private $tag;
    /** @var string */
    private $attribute;

    public $connectname;
    public $connectpass;

    public function __construct($format_res, $flname)
    {
        require_once('config.php');
        // Turn up error reporting
        error_reporting(E_ALL | E_STRICT);

        // Turn off WSDL caching
        ini_set('soap.wsdl_cache_enabled', 0);

        // Define credentials for LD
        define ('USERNAME', $this->connectname);
        define ('PASSWORD', $this->connectpass);

        // SOAP WSDL endpoint
        define ('ENDPOINT', 'https://api.livedocx.com/2.1/mailmerge.asmx?wsdl');

        // Define timezone
        date_default_timezone_set('Europe/Berlin');

        // Instantiate SOAP object and log into LiveDocx
        $this->soap = new SoapClient(ENDPOINT);

        $this->soap->LogIn(
            array('username' => USERNAME, 'password' => PASSWORD)
        );

        // Upload template
        $this->data = file_get_contents('Original/' . $format_res);

        $this->soap->SetLocalTemplate(
            array('template' => base64_encode($this->data), 'format' => 'docx')
        );

        $this->result = $this->soap->RetrieveDocument(
            array('format' => 'html')
        );

        $this->data = $this->result->RetrieveDocumentResult;

        $exceptions = array(
            'a'   => array('href'),
            'img' => array('src')
        );

        $this->stripAttributes($exceptions);

        file_put_contents('Recode/' . $flname . '.html', base64_decode($this->data));
    }

    public function stripAttributes(array $exceptions)
    {
        $dom = new DOMDocument();
        $dom->strictErrorChecking = false;
        $dom->formatOutput = true;
        $dom->loadHTML(base64_decode($this->data));

        $xpath = new DOMXPath($dom);
        if (false === ($elements = $xpath->query("//*"))) die('Xpath error!');

        /** @var $element DOMElement */
        foreach ($elements as $element) {
            for ($i = $element->attributes->length; --$i >= 0;) {
                $this->tag       = $element->nodeName;
                $this->attribute = $element->attributes->item($i)->nodeName;

                if ($this->checkAttrExceptions($exceptions)) continue;

                $element->removeAttribute($this->attribute);
            }
        }

        $this->data = base64_encode($dom->saveHTML());
    }

    public function checkAttrExceptions(array $exceptions)
    {
        foreach ($exceptions as $tag => $attributes) {
            if (empty($attributes) || !is_array($attributes)) {
                die('Attributes not set!');
            }

            foreach ($attributes as $attribute) {
                if ($tag === $this->tag && $attribute === $this->attribute) {
                    return true;
                }
            }
        }

        return false;
    }
}

如果您需要添加更多属性例外,只需编辑$exceptions数组即可。例如,如果您不希望所有“a”标记中的条带title属性修改例外:

$exceptions = array(
    'a'   => array('href', 'title'),
    'img' => array('src')
);