Converter HTML para XML

Eu tenho hundereds de arquivos HTML que precisam ser mostrados em XML. Estamos usando estes HTML para servir conteúdo para aplicações, mas agora temos que servir esses conteúdos como XML.

os ficheiros HTML são contains, tables, div's, image's, p's, b ou strong tags, etc..

Pesquisei no Google e encontrei algumas aplicações, mas ainda não me apetecia.

pode sugerir uma forma de converter estes conteúdos de ficheiros para XML?

 14
Author: bahadir arslan, 2012-05-07

3 answers

Fui bem sucedido ao usar {[[0]} o utilitário da linha de comandos. No linux eu instalei-o rapidamente com apt-get install tidy. Então o comando:

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

Deu um ficheiro xml, que fui capaz de processar com o processador xslt. No entanto, eu precisava configurar xhtml1 dtds corretamente.

Esta é a sua página inicial: html-tidy.org (e o legacy one: HTML Tidy)

 16
Author: Jarekczek, 2017-12-13 15:06:27

Eu encontrei uma maneira de converter (mesmo mau) html em XML bem formado. Comecei a basear isto na função DOM loadHTML. No entanto, durante o tempo vários problemas ocorreram e eu otimizei e adicionei patches para corrigir os efeitos colaterais.

  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(!@$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;
        } ;
    }

Agora isso também permite adicionar mais peças html em um XML que eu precisava usar a mim mesmo. Em geral, pode ser usado assim:

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

Neste exemplo '<p>test<font>two</p>' será muito bem apresentado em XML bem formado como ' <info><p>test<font>two</font></p></info>'. A marca de raiz da informação é adicionado como também permitirá converter '<p>one</p><p>two</p> ' que não é XML, uma vez que não tem um elemento raiz. No entanto, se o html tiver de certeza um elemento raiz, então a marca raiz extra <info> poderá ser ignorada.

Com isto, estou a obter um XML muito bom a partir de HTML não estruturado e até corrompido! Espero que seja um pouco claro e possa contribuir para que outras pessoas o usem.
 2
Author: Bob Siefkes, 2013-08-17 19:22:24

Lembre-se que HTML e XML são dois conceitos distintos na árvore de linguagens de marcação. Você não pode exatamente Substituir HTML por XML . XML pode ser visto como uma forma generalizada de HTML, mas mesmo isso é impreciso. Você usa principalmente HTML para exibir dados, e XML para transportar(ou armazenar) os dados.

Este link é útil: Como ler HTML como XML?

Mais aqui - diferença entre HTML e XML

 1
Author: Coffee, 2017-05-23 12:09:58