Parse ncx (xml) with Java to change PlayOrder
probably a newbie question but, I'm trying to parse and change an ncx-file (important in the ePub-format) with Java to make sure that the PlayOrder attribute is in, well, the right order (1,2,3,4...). This is my java so far, it works pretty well but it sets the PlayOrder to (1,3,5,7...). Guess it's parsing one tag to much (). Any ideas?
package com.mkyong.common;
import java.io.File;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
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.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class ModifyXMLFile {
public static void main(String argv[]) {
try{
String filepath = "toc.ncx";
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.parse(filepath);
//Get the root element
Node company = doc.getFirstChild();
//Get the staff element , it may not working if tag has spaces, or
//whatever weird characters in front...it's better to use
//getElementsByTagName() to get it directly.
//Node staff = company.getFirstChild();
//Get the staff element by tag name directly
Node navPoint = doc.getElementsByTagName("navMap").item(0);
//update staff attribute
/*NamedNodeMap attr = navPoint.getAttributes();
Node nodeAttr = attr.getNamedItem("navPoint");
nodeAttr.setTextContent("2");*/
//append a new node to staff
/*Element age = doc.createElement("age");
age.appendChild(doc.createTextNode("28"));
staff.appendChild(age);*/
//loop the staff child node
NodeList list = navPoint.getChildNodes();
for (int i =0; i<list.getLength();i++){
Node node = list.item(i);
//get the salary element, and update the value
NamedNodeMap attr = node.getAttributes();
if(attr != null){
Node nodeAttr = attr.getNamedItem("playOrder");
System.out.println(nodeAttr);
String aString = Integer.toSt开发者_高级运维ring(i);
nodeAttr.setTextContent(aString);
}
}
//write the content into xml file
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File(filepath));
transformer.transform(source, result);
System.out.println("Done");
}catch(ParserConfigurationException pce){
pce.printStackTrace();
}catch(TransformerException tfe){
tfe.printStackTrace();
}catch(IOException ioe){
ioe.printStackTrace();
}catch(SAXException sae){
sae.printStackTrace();
}
}
}
My guess: navPoint.getChildNodes()
gets more than the navPoint elements, The XPath "/ncx/navMap/node()" in Oxygen yields also the (invisible) text nodes between the novPoint elements.
Because they don't have attributes, if(attr != null)
skips them, thus only every second node is handled, thus only every second value of i is used.
Is there a getChildElements()
?
Best regards,
Christian
精彩评论