Is the standard library my best option for Java to load/read and edit/modify and save a html file with no reformatting?

Viewed 73

I want to load/read and edit/modify and save a html file located on my hard drive. I tried JSOUP, but it kept reformatting the html file. I want to avoid reformating.

I'm wanting to inject some JavaScript after the <script> and before var deviceReady = false; in the html file.

Do I need to parse the file?

Should I use default Java? (BufferedReader, FileReader, Scanner)

<!DOCTYPE html>
<html lang="en">
<head>
<meta name='viewport' content='initial-scale = 1, minimum-scale = 1, maximum-scale = 1'/>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="x-ua-compatible" content="IE=10">
<title>LX-XXX-KU</title>
<style type="text/css">#initialLoading{background:url(assets/htmlimages/loader.gif) no-repeat center 
center;background-color:#ffffff;position:absolute;margin:auto;top:0;left:0;right:0;bottom:0;z- 
index:10010;}</style>

"

<script>

var deviceReady = false;
var initCalled = false ;
var initialized = false;

function onBodyLoad()
{
 if(typeof window.device === 'undefined')
{
    document.addEventListener("deviceready", onDeviceReady, false);
}
else
 {
    onDeviceReady();
 }
}

Javasacript I want to add after the <script> and before var deviceReady = false;

`//adds numbers to TOC
window.addEventListener( 'moduleReadyEvent', function ( e )
{
var myText = document.getElementsByClassName('tocText');

for ( var i = 0; i < myText.length; i++ )
{
var getText = myText[ i ].childNodes;
var str = ( i + 1 ) + ' ' + getText[ 0 ].innerHTML;
getText[ 0 ].innerHTML = str;
}
});`
2 Answers

This can be accomplished like so:

File f = ...;
String contents = new String(Files.readAllBytes(f));
int idx = contents.indexOf(insertBeforeStr);
contents = contents.substring(0, idx) + contentToBeAdded + contents.substring(idx + 1);

// write contents back to the disk.

If you turn off jsoup's pretty printing option, and use the XML parser instead of the validating HTML parser, the document and all of its text verbatim, including whitespace, is passed through pretty much unmolested, other than syntax fixes for attributes, missing end tags, and the like.

See for example your input on Try jsoup with pretty-printing off, and using the XML parser, is effectively the same as your original.

The code would be something like:

Document doc = Jsoup.parse("<script>\nSomething(); ", "", Parser.xmlParser());
doc.outputSettings().prettyPrint(false);

Element scriptEl = doc.selectFirst("script");
DataNode scriptData = scriptEl.dataNodes().get(0);
scriptData.setWholeData(scriptData.getWholeData() + "\nanotherFunction();");

System.out.println(doc.html());

Gives us (note that there's no HTML structure automatically created, due to using the XML parser):

<script>
Something(); 
anotherFunction()</script>

ControlAltDel's answer definitely works and means you can do it with just the Java base library. The benefit of using jsoup is (IMHO - as the author of jsoup) in this case is that you're not trying to string-match HTML, and won't get caught by e.g. a <script> in a comment, or in this case a missing close </script> tag, etc. But of course YMMV.

Incidentally, once jsoup 1.14.1 is released (soon!) with the change #1419 (which for script elements, proxies text settings into data without escaping), the code will simplify to:

Element scriptEl = doc.selectFirst("script");
scriptEl.appendText("\nanotherFunction()");
Related