2

我在 Java 中使用 DOM 解析器将子节点添加到现有节点中。

我的 XML 是

<?xml version="1.0" encoding="iso-8859-1"?>
 <chart> 
<chart renderTo="pieContainer" defaultSeriesType="pie" zoomType="xy" plotBackgroundColor="null" plotBorderWidth="null"  plotShadow="false"></chart>
<legend id="legendNode">
  <align>center</align>
  <backgroundColor>null</backgroundColor>
  <borderColor>#909090</borderColor> 
  <borderRadius>25</borderRadius>
</legend>
 </chart>

有没有办法直接在现有节点下添加子节点?我可以使用这样的东西吗?

Node myNode = nodesTheme.item(0);
this.widgetDoc.getElementById("/chart/legend").appendChild(myNode);

我的代码

import org.w3c.dom.*;
import javax.xml.parsers.*;
public class TestGetElementById {
    public static void main(String[] args) throws Exception {

        String widgetXMLFile = "piechart.xml";
        DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();

        domFactory.setNamespaceAware(true);
        DocumentBuilder docBuilder = domFactory.newDocumentBuilder();
        Document doc = docBuilder.parse(widgetXMLFile);
        Node n = doc.getElementById("/chart/legend");
        //Node n = doc.getElementById("legendTag");

        Element newNode = doc.createElement("root");
        n.appendChild(newNode);
    }
}
4

2 回答 2

3

编辑:对原始问题:是的,appendChild 的工作方式与您计划的方式相同,问题在于 getElementById。

NullPointerException 表示没有具有该 ID 的元素。javadoc给出了它:

http://docs.oracle.com/javase/1.5.0/docs/api/org/w3c/dom/Document.html#getElementById(java.lang.String)

DOM 实现应使用属性 Attr.isId 来确定属性是否属于 ID 类型。

并进一步在 Attr 的文档中:

http://docs.oracle.com/javase/1.5.0/docs/api/org/w3c/dom/Attr.html#isId()

所以基本上你的文档需要一个 DTD 或一个模式,并且需要设置

DocumentBuilderFactory.setValidating(true)

或手动设置 IsId 属性。

我个人使用:(dirty&scala 表示懒惰)

import org.w3c.dom.{Document,Node,Attr,Element}

def idify ( n:Node ) {
  if ( n.getNodeType() == Node.ELEMENT_NODE ){
        val e = n.asInstanceOf[Element ]
        if (e.hasAttributeNS(null , "id" ) )e.setIdAttributeNS(null , "id" , true )
  }
  val ndlist = n.getChildNodes()
  for ( i <- 0 until ndlist.getLength ) idify(ndlist.item(i) )
}

肯定有更专业的方法可以做到这一点,而不涉及起草完整的 DTD/模式。如果有人知道,我也很好奇。

于 2013-08-08T11:58:09.800 回答
2

getElementById专门用于通过id属性检索 DOM 元素。试试这个:

this.widgetDoc.getElementById("legendNode").appendChild(myNode);

有关检索 DOM 节点的其他方法,请查看querySelectorquerySelectorAll.

于 2012-04-18T11:07:49.687 回答