2012-05-06 19 views
12

Tengo un montón de archivos HTML que deben ser tratados en XML. Estamos utilizando estos HTML para servir los contenidos de las aplicaciones, pero ahora debemos servir estos contenidos como XML.Conversión de HTML a XML

archivos HTML son contiene, tablas, divs, la imagen de p, de etiquetas, b o fuertes, etc ..

que Google y encontró algunas aplicaciones pero no podía achive todavía.

¿Podría sugerir una forma de convertir el contenido de estos archivos a XML?

+0

Eche un vistazo a [esta publicación] (http://stackoverflow.com/a/85922/938089). Luego, eche un vistazo muy de cerca al [cuarto comentario] (http://stackoverflow.com/questions/84556/#comment1436887_85922). ¿Por qué quieres convertir HTML a XML? –

+0

@RobW lo comprobaré. Estábamos sirviendo HTML como contenido para algunas aplicaciones, pero ahora tenemos que servir como XML. –

+0

@RobW, también sé las diferencias entre XML y HTML. Pero necesito analizar su contenido y ponerlo en XML. –

Respuesta

15

tuve éxito con la utilidad de línea de comandos tidy. En Linux lo instalé rápidamente con apt-get install tidy. A continuación, el comando:

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

dio un archivo XML, que yo era capaz de procesar con el procesador XSLT. Sin embargo, necesitaba configurar xhtml1 dtds correctamente.

Esta es su página de inicio: html-tidy.org (y el legado uno: HTML Tidy)

+4

También hay xmllint -html -xmlout –

+2

También lo uso a veces. Creo que deberías hacer una respuesta por separado. – Jarekczek

+0

elimina el javascript del archivo html – Alaa

1

Recuerde que HTML y XML son dos conceptos distintos en el árbol de lenguajes de marcado. No se puede exactamente replace HTML with XML. XML se puede ver como una forma generalizada de HTML, pero incluso eso es impreciso. Utiliza principalmente HTML para visualizar datos y XML para transportar (o almacenar) los datos.

Este enlace es muy útil: How to read HTML as XML?

More here - difference between HTML and XML

+0

HTML __is__ XML. – bfontaine

+10

@boudou. No, XHTML es XML, HTML no lo es. – Bruno

+1

Entonces, ¿qué sugieres? Si primero convierto HTML a XHTML, ¿puedo convertirlo fácilmente en XML? –

2

me encontré una forma de convertir (aunque mal) HTML en XML bien formado. Empecé a basar esto en la función DOM loadHTML. Sin embargo, durante el tiempo ocurrieron varios problemas y optimicé y agregué parches para corregir los efectos secundarios.

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; 
     } ; 
    } 

Ahora esto también permite agregar más piezas html en un XML que necesitaba usar yo mismo. En general se puede utilizar como este:

 $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>'; 

En este ejemplo '<p>test<font>two</p>' será muy bien ser outputed en XML bien formado como '<info><p>test<font>two</font></p></info>'. La etiqueta raíz de información se agrega ya que también permitirá convertir '<p>one</p><p>two</p>', que no es XML, ya que no tiene un elemento raíz. Sin embargo, si html tiene un elemento raíz, se puede omitir la etiqueta raíz extra <info>.

¡Con esto obtengo un buen XML real de HTML no estructurado e incluso corrupto!

Espero que sea un poco claro y podría contribuir a que otras personas lo usen.

+1

¿Es este código PHP? –