建立通用 XML 遞迴遍歷基礎元件,提取所有元素節點的 XPath 路徑與文字值,為複雜解析邏輯奠基。採用 DOM4J 庫實作,支援屬性、命名空間、混合內容等實際場景。
import org.dom4j.*;
import java.util.*;
public class XmlTest {
private static List<Leaf> elemList = new ArrayList<>();
private static String srcXml = "\n" +
"\n" +
" \n" +
" 某人 \n" +
" \n" +
" \n" +
" 10002 \n" +
" 西安市太白路 \n" +
" \n" +
" 10002 空ID節點啊 \n" +
" 10002 空ID節點啊 \n" +
" 西安市太白路2 \n" +
" \n" +
" \n" +
" ASDF \n" +
" ";
public static void main(String[] args) throws DocumentException {
XmlTest test = new XmlTest();
Element root = test.getRootElement();
test.getElementList(root);
String result = test.getListString(elemList);
System.out.println("-----------原XML內容------------");
System.out.println(srcXml);
System.out.println("-----------解析結果------------");
System.out.println(result);
}
public Element getRootElement() throws DocumentException {
return DocumentHelper.parseText(srcXml).getRootElement();
}
// 遞迴遍歷核心邏輯
public void getElementList(Element element) {
List elements = element.elements();
if (elements.isEmpty()) {
// 葉子節點:記錄 XPath 與文字值
elemList.add(new Leaf(element.getPath(), element.getTextTrim()));
} else {
// 非葉子節點:遞迴處理子元素
for (Iterator it = elements.iterator(); it.hasNext();) {
getElementList((Element) it.next());
}
}
}
public String getListString(List<Leaf> list) {
StringBuffer sb = new StringBuffer();
for (Leaf leaf : list) {
sb.append(leaf.getXpath()).append(" = ").append(leaf.getValue()).append("\n");
}
return sb.toString();
}
}
// 資料結構:封裝 XPath 與值
class Leaf {
private String xpath, value;
public Leaf(String xpath, String value) { this.xpath = xpath; this.value = value; }
public String getXpath() { return xpath; }
public String getValue() { return value; }
public void setXpath(String xpath) { this.xpath = xpath; }
public void setValue(String value) { this.value = value; }
}
-----------解析結果------------
/doc/person/name = 某人
/doc/person/adds/add/BS = 10002
/doc/person/adds/add/note = 西安市太白路
/doc/person/adds/add/BS = 10002
/doc/person/adds/add/note = 空ID節點啊
/doc/person/adds/add/BS = 10002
/doc/person/adds/add/note = 空ID節點啊
/doc/person/adds/add/*[name()='BS'] =
/doc/person/adds/add/note = 西安市太白路2
/doc/other/name = ASDF
<add> 產生相同 XPath,實際應用需結合索引或屬性區分(如 /add[1]/BS)<BS xmlns="10001"/> 產生特殊 XPath *[name()='BS'],需針對命名空間增強解析element.attributes())Leaf 擴充為包含節點類型、屬性 Map、命名空間上下文的豐富模型[1], [2])區分同級同名元素