L'informatique pour les littéraires

Java: rename xml / html nodes

Petit script permettant de renommer les élements dans un fichier xml.

Pourquoi Java?

Il existe une norme w3c avec l’instruction « renameNode » qui m’aurait beacoup servi si elle avait été implémentée en javascript… malheureusement, rien à faire, pour l’instant aucun navigateur ne l’a mise en place.

Par ailleurs, Firefox bloque la plupart des instructions visant la modification d’une partie d’un dom (document object model). J’ai donc du me résoudre à revenir à du JAVA pour faire cette modification.

Transformer Roméo et Juliette

Il y a quelques années, la totalité des pièces de Shakespeare a été encodée en xml dans le cadre de l’initiative TEI5. C’était un projet fou mais qui permet d’avoir une structure très complète de balises: un élément pour un SPEECH, un élément pour le SPEAKER, un élément pour une LINE de texte. Les STAGEDIR sont également annotées ce qui permet de mettre très facilement en forme chaque partie du texte avec votre CSS.

Mais pour parvenir à ce résultat, nous devons passer par un changement de taille. Le xml de base utilise directement les balises SPEECH, SPEAKER, LINE ou STAGEDIR. Pour réussir notre epub, il faut passer à du html, c’est à dire à des balises de type DIV, P, H1…

Pour cela nous copions le nom de la balise et le mettons dans la classe.

<SPEECH>
  <SPEAKER>SAMPSON</SPEAKER>
  <LINE>Gregory, o' my word, we'll not carry coals.</LINE>
</SPEECH>

Devient

<div class="SPEECH">
   <p class="SPEAKER">SAMPSON</p>
   <p class="LINE">Gregory, o' my word, we'll not carry coals.</p>
</div>

Cela est très facile grâce à la fonction element.classList.add(element.tagName()) en javascript.

Il serait possible de tout simplement remplacer les texte des balises… malheureusement, ce qui est facile pour le tag de début, est très difficile à maintenir pour les tag de fin. Et la fonction renameNode du dom3 core n’est pas implémentée par le différents navigateurs, ni par les frameworks comme jquery ou node.js.

J’ai dû passé à java! Qui contient renameNode, mais qui n’a ps de fonction simple d’ajout d’une classe 🤔

package MyPackage;

import java.io.File;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
 
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerException;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
 
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
 
public class DomParserExample {
 
     public static void main(String[] args) throws ParserConfigurationException,
          SAXException, IOException {
 
    	//Get Document Builder
          DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
          DocumentBuilder builder = factory.newDocumentBuilder();
 
          // Load the input XML document
          Document document = builder.parse(new File("Romeo_and_Juliet.xml"));
 

          NodeList nodeList = document.getDocumentElement().getElementsByTagName("*");
          for (int i = 0; i < nodeList.getLength(); i++) {
               Node node = nodeList.item(i);
 
               if (node.getNodeType() == Node.ELEMENT_NODE) {
                    Element elem = (Element) node;
						
						System.out.println(elem.getTagName());
						elem.setAttribute("class", elem.getTagName());
						document.renameNode(elem, null, "p");
						System.out.println(elem.toString());
						
						
		// output DOM XML to console 
		try {
            Transformer transformer = TransformerFactory.newInstance().newTransformer();
            transformer.setOutputProperty(OutputKeys.INDENT, "yes"); 

			
	//Write XML to file
	FileOutputStream outStream = new FileOutputStream(new File("result.xml")); 
			
	transformer.transform(new DOMSource(document), new StreamResult(outStream));
			
			 } 
    catch (TransformerException e) 
    {
        e.printStackTrace();
    }
    catch (Exception e) 
    {
        e.printStackTrace();
    }
              
               }
          }
 

     }
}

Sources