2012-05-06 23 views
12

私は、XMLに変換する必要があるHTMLファイルを手に入れました。これらのHTMLを使用してアプリケーション用のコンテンツを提供していますが、今はこれらのコンテンツをXMLとして提供する必要があります。HTMLをXMLに変換する

のHTMLファイルが含まれている、テーブル、のdivの、画像の、Pさん、Bまたは強いタグなど。

私はGoogleで検索し、見つかったいくつかのアプリケーションをしかし、私はまだachiveことができませんでした。

これらのファイルの内容をXMLに変換する方法を提案できますか?

+0

[this post](http://stackoverflow.com/a/85922/938089)をご覧ください。その後、[第4のコメント](http://stackoverflow.com/questions/84556/#comment1436887_85922)をよく見てください。なぜHTMLをXMLに変換したいのですか? –

+0

@RobW私はそれをチェックします。私たちはHTMLをいくつかのアプリケーションのコンテンツとして提供していましたが、今はXMLとしての役割を果たす必要があります。 –

+0

@RobW、また私はXMLとHTMLの違いを知っています。しかし、私はその内容を解析してXMLを入力する必要があります。 –

答えて

15

私はtidyコマンドラインユーティリティを使用して成功しました。 Linuxの場合、私はapt-get install tidyですばやくインストールしました。次に、コマンド:

tidy -q -asxml --numeric-entities yes source.html >file.xml

は、私は、XSLTプロセッサで処理することができたxmlファイルを、与えました。しかし、私はxhtml1 dtdsを正しく設定する必要がありました。私が整形XMLに(でも悪い)HTMLに変換する方法を発見したの

+4

xmllint -html -xmlout –

+2

私も時々使用します。私はあなたがそれから別の答えを出すべきだと思います。 – Jarekczek

+0

htmlファイルからjavascriptを削除します – Alaa

1

HTMLとXMLは、マークアップ言語のツリーの2つの異なる概念です。正確にはreplace HTML with XMLとすることはできません。 XMLはHTMLの一般化された形式として見ることができますが、それは不正確です。主にHTMLを使用してデータを表示し、XMLを使用してデータを格納(または格納)します。

このリンクは便利です:How to read HTML as XML?

More here - difference between HTML and XML

+0

HTML __is__ XML。 – bfontaine

+10

@boudou。いいえ、XHTMLはXMLですが、HTMLはありません。 – Bruno

+1

あなたは何を提案しますか?最初にHTMLをXHTMLに変換すると、XMLで簡単に変換できますか? –

2

html-tidy.orgHTML Tidyとレガシー1:)

これは彼らのホームページです。私はこれをDOM loadHTML関数に基づいて始めました。しかし、時間の経過とともにいくつかの問題が発生し、私は副作用を修正するためのパッチを最適化して追加しました。

function tryToXml($dom,$content) { 
    if(!$content) return false; 

    // xml well formed content can be loaded as xml node tree 
    $fragment = $dom->createDocumentFragment(); 
    // wonderfull appendXML to add an XML string directly into the node tree! 

    // aappendxml will fail on a xml declaration so manually skip this when occurred 
    if(substr($content,0, 5) == '<?xml') { 
     $content = substr($content,strpos($content,'>')+1); 
     if(strpos($content,'<')) { 
     $content = substr($content,strpos($content,'<')); 
     } 
    } 

    // if appendXML is not working then use below htmlToXml() for nasty html correction 
    if([email protected]$fragment->appendXML($content)) { 
     return $this->htmlToXml($dom,$content); 
    } 

    return $fragment; 
    } 



    // convert content into xml 
    // dom is only needed to prepare the xml which will be returned 
    function htmlToXml($dom, $content, $needEncoding=false, $bodyOnly=true) { 

    // no xml when html is empty 
    if(!$content) return false; 

    // real content and possibly it needs encoding 
    if($needEncoding) { 
     // no need to convert character encoding as loadHTML will respect the content-type (only) 
     $content = '<meta http-equiv="Content-Type" content="text/html;charset='.$this->encoding.'">' . $content; 
    } 

    // return a dom from the content 
    $domInject = new DOMDocument("1.0", "UTF-8"); 
    $domInject->preserveWhiteSpace = false; 
    $domInject->formatOutput = true; 

    // html type 
    try { 
     @$domInject->loadHTML($content); 
    } catch(Exception $e){ 
     // do nothing and continue as it's normal that warnings will occur on nasty HTML content 
    } 
     // to check encoding: echo $dom->encoding 
     $this->reworkDom($domInject); 

    if($bodyOnly) { 
     $fragment = $dom->createDocumentFragment(); 

     // retrieve nodes within /html/body 
     foreach($domInject->documentElement->childNodes as $elementLevel1) { 
     if($elementLevel1->nodeName == 'body' and $elementLevel1->nodeType == XML_ELEMENT_NODE) { 
     foreach($elementLevel1->childNodes as $elementInject) { 
      $fragment->insertBefore($dom->importNode($elementInject, true)); 
     } 
     } 
     } 
    } else { 
     $fragment = $dom->importNode($domInject->documentElement, true); 
    } 

    return $fragment; 
    } 



    protected function reworkDom($node, $level = 0) { 

     // start with the first child node to iterate 
     $nodeChild = $node->firstChild; 

     while ($nodeChild) { 
      $nodeNextChild = $nodeChild->nextSibling; 

      switch ($nodeChild->nodeType) { 
       case XML_ELEMENT_NODE: 
        // iterate through children element nodes 
        $this->reworkDom($nodeChild, $level + 1); 
        break; 
       case XML_TEXT_NODE: 
       case XML_CDATA_SECTION_NODE: 
        // do nothing with text, cdata 
        break; 
       case XML_COMMENT_NODE: 
        // ensure comments to remove - sign also follows the w3c guideline 
        $nodeChild->nodeValue = str_replace("-","_",$nodeChild->nodeValue); 
        break; 
       case XML_DOCUMENT_TYPE_NODE: // 10: needs to be removed 
       case XML_PI_NODE: // 7: remove PI 
        $node->removeChild($nodeChild); 
        $nodeChild = null; // make null to test later 
        break; 
       case XML_DOCUMENT_NODE: 
        // should not appear as it's always the root, just to be complete 
        // however generate exception! 
       case XML_HTML_DOCUMENT_NODE: 
        // should not appear as it's always the root, just to be complete 
        // however generate exception! 
       default: 
        throw new exception("Engine: reworkDom type not declared [".$nodeChild->nodeType. "]"); 
      } 
      $nodeChild = $nodeNextChild; 
     } ; 
    } 

これで、自分で使用する必要がある1つのXMLにさらに多くのhtmlファイルを追加することができます。 '<p>test<font>two</p>'がうまく「<info><p>test<font>two</font></p></info>」として整形式XMLの中outputedするこの例で

 $c='<p>test<font>two</p>'; 
    $dom=new DOMDocument('1.0', 'UTF-8'); 

$n=$dom->appendChild($dom->createElement('info')); // make a root element 

if($valueXml=tryToXml($dom,$c)) { 
    $n->appendChild($valueXml); 
} 
    echo '<pre/>'. htmlentities($dom->saveXml($n)). '</pre>'; 

:一般的には次のように使用することができます。情報ルートタグは追加されており、ルート要素が1つではないため、XMLではない '<p>one</p><p>two</p>'も変換できます。しかし、もしhtmlが確かに1つのルート要素を持っていれば、余分なルート<info>タグをスキップすることができます。

これで、私は構造化されていない、さらには破損したHTMLから本当に素敵なXMLを手に入れました!

私はそれが少しはっきりしていて、他の人に使ってもらえると願っています。

+1

このPHPコードはありますか? –

関連する問題