用Java解析ncx(xml)来改变PlayOrder
可能是一个新手问题,但是,我正在尝试使用 Java 解析和更改 ncx 文件(在 ePub 格式中很重要),以确保 PlayOrder 属性处于正确的顺序(1,2,3, 4...)。 到目前为止,这是我的 java,它运行得很好,但它将 PlayOrder 设置为(1,3,5,7...)。猜测它正在解析一个标签太多()。有什么想法吗?
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.toString(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();
}
}
}
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.toString(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();
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我的猜测:
navPoint.getChildNodes()
获取的不仅仅是 navPoint 元素,Oxygen 中的 XPath“/ncx/navMap/node()”还产生 novPoint 元素之间的(不可见的)文本节点。因为它们没有属性,所以
if(attr != null)
会跳过它们,因此仅处理每隔一个节点,因此仅使用 i 的每隔一个值。有 getChildElements() 吗?
最好的问候,
克里斯蒂安
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