Java SAX解析和父/子关系
所以我面临这个问题,需要解析一个XML文件来传播域对象。听起来很简单,但是,XML文件中的元素可以有未知的子元素数量,因此域对象可以有一个指向类的另一个对象的实例变量,该对象可以有一个指向同一个类的实例变量的变量,依此类推。为给您提供一个示例,这是为XML文件提供的一个示例:Java SAX解析和父/子关系,java,xml,parsing,dom,sax,Java,Xml,Parsing,Dom,Sax,所以我面临这个问题,需要解析一个XML文件来传播域对象。听起来很简单,但是,XML文件中的元素可以有未知的子元素数量,因此域对象可以有一个指向类的另一个对象的实例变量,该对象可以有一个指向同一个类的实例变量的变量,依此类推。为给您提供一个示例,这是为XML文件提供的一个示例: <categories> <category id="1"> <name>XML</name> <category id="2"
<categories>
<category id="1">
<name>XML</name>
<category id="2">
<name>XPath</name>
</category>
<category id="3">
<name>XML Schema</name>
</category>
<category id="4">
<name>XSLT</name>
</category>
<category id="5">
<name>XSL-FO</name>
</category>
<category id="6">
<name>XQuery</name>
</category>
</category>
<category id="7">
<name>Java</name>
<category id="100">
<name>SDK</name>
<category id="8">
<name>Collections</name>
</category>
<category id="9">
<name>NIO</name>
</category>
<category id="10">
<name>Concurrency</name>
</category>
</category>
<category id="1000">
<name>EE</name>
<category id="11">
<name>EJB</name>
</category>
<category id="12">
<name>Web</name>
</category>
<category id="13">
<name>Webservices</name>
</category>
</category>
<category id="0">
<name>Examen boeken</name>
</category>
</category>
</categories>
XML
XPath
XML模式
XSLT
XSL-FO
函数
JAVA
SDK
收藏
尼奥
并发性
EE
EJB
网状物
网络服务
博肯考试
我已经用DOM解析器完成了这项工作,但在我的研究中,我还需要用SAX解析器完成这项工作。我被困在一个点上,我需要告诉哪个元素有哪个元素作为子元素,哪个元素有哪个元素作为父元素
到目前为止,我设法在一个包含其ID和名称的映射中获取所有类别条目
代码如下所示:
public static void main(String[] args) throws SAXException, IOException,
ParserConfigurationException {
Bookshelf mijnBookshelf = new Bookshelf("boekenfestijn");
Map<Integer, Category> categories = new HashMap<Integer, Category>();
// TODO inlezen
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
DefaultHandler handler = new DefaultHandler() {
String reading = null;
boolean inCategory = false;
boolean inName = false;
int categoryId;
Category currentCategory;
public void startElement(String uri, String localName,
String qName, Attributes attributes)
throws SAXException {
if(qName.equalsIgnoreCase("CATEGORY") && attributes.getValue("id") != null){
inCategory = true;
categoryId = Integer.parseInt(attributes.getValue("id"));
System.out.println("START HANDLING ID -> " + attributes.getValue("id"));
}
if(qName.equalsIgnoreCase("NAME")){
inName = true;
}
}
public void endElement(String uri, String localName,
String qName) throws SAXException {
if(inCategory){
inCategory = false;
System.out.println("CATEGORY ID : " + categoryId + " NAME : " + reading);
currentCategory = new Category(categoryId, reading);
currentCategory.setBookshelf(mijnBookshelf);
categories.put(categoryId, currentCategory);
System.out.println("END HANDLING");
}
if(inName){
inName = false;
}
}
public void characters(char ch[], int start, int length)
throws SAXException {
reading = new String(ch, start, length);
}
};
saxParser.parse("bookshelf.xml", handler);
} catch (Exception e) {
e.printStackTrace();
}
for (Integer i : categories.keySet()) {
System.out.println("ID: " + categories.get(i).getId() + "->"
+ categories.get(i).getName());
}
publicstaticvoidmain(字符串[]args)抛出SAXException、IOException、,
ParserConfiguration异常{
书架mijnBookshelf=新书架(“boekenfestijn”);
映射类别=新HashMap();
//托多因莱森
试一试{
SAXParserFactory=SAXParserFactory.newInstance();
SAXParser SAXParser=factory.newSAXParser();
DefaultHandler=新的DefaultHandler(){
字符串读取=空;
布尔内分类=假;
布尔inName=false;
int分类;
类别当前类别;
public void startElement(字符串uri、字符串localName、,
字符串(名称、属性)
抛出SAX异常{
if(qName.equalsIgnoreCase(“CATEGORY”)和&attributes.getValue(“id”)!=null){
增加类别=正确;
categoryId=Integer.parseInt(attributes.getValue(“id”);
System.out.println(“开始处理ID->”+attributes.getValue(“ID”);
}
if(qName.equalsIgnoreCase(“名称”)){
inName=true;
}
}
public void endElement(字符串uri、字符串localName、,
字符串(qName)引发异常{
如果(属范畴){
属范畴=假;
System.out.println(“类别ID:+categoryId+”名称:+reading);
currentCategory=新类别(categoryId,reading);
currentCategory.setBookshelf(mijnBookshelf);
categories.put(categoryId,currentCategory);
System.out.println(“末端处理”);
}
如果(名称){
inName=false;
}
}
公共无效字符(字符ch[],整数开始,整数长度)
抛出SAX异常{
读取=新字符串(ch、开始、长度);
}
};
parse(“bookshelf.xml”,handler);
}捕获(例外e){
e、 printStackTrace();
}
对于(整数i:categories.keySet()){
System.out.println(“ID:+categories.get(i).getId()+”->”
+categories.get(i.getName());
}
对于“类别”类
公共类类别{
私有整数id;
私有字符串名称;
私人类别家长;
private List children=new ArrayList();
私人书架;
公共类别(){
}
公共类别(整数id、字符串名称){
超级();
this.id=id;
this.name=名称;
}
公共整数getId(){
返回id;
}
公共无效集合id(整数id){
this.id=id;
}
公共字符串getName(){
返回名称;
}
公共void集合名(字符串名){
this.name=名称;
}
公共类别getParent(){
返回父母;
}
公共无效集合父对象(类别父对象){
this.parent=parent;
}
公共列表getChildren(){
返回儿童;
}
公共字符串toString(){
字符串s=bookshelf.getName()+“/”;
如果(父项!=null){
s=父级.toString();
}
s+=名称+“/”;
返回s;
}
公共书架getBookshelf(){
归还书架;
}
公共书架(书架){
this.bookshelf=书架;
}
这就是我陷入困境的地方?我如何继续定义父子关系?我如何知道在处理程序中的任何一点上,哪个元素的子元素/父元素
任何帮助都将不胜感激
TLDR:在使用sax解析器填充域对象时,如何定义父/子关系?在sax中,您无法直接知道哪个元素是另一个元素的父元素。处理此信息的常用方法是管理后进先出堆栈(例如,
java.util.stack
)。将元素推到startElement()上
方法,并将其弹出到endElement()
上
不幸的是,由于SAX中的
startElement()
,您无法直接知道哪个元素是另一个元素的父元素。处理此信息的常用方法是管理后进先出堆栈(例如java.util.stack
)。在startElement()
方法上推送元素,然后在endElement()
上弹出它
不幸的是
public class Category {
private Integer id;
private String name;
private Category parent;
private List<Category> children = new ArrayList<Category>();
private Bookshelf bookshelf;
public Category(){
}
public Category(Integer id, String name) {
super();
this.id = id;
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Category getParent() {
return parent;
}
public void setParent(Category parent){
this.parent = parent;
}
public List<Category> getChildren() {
return children;
}
public String toString() {
String s = bookshelf.getName() + "/";
if (parent != null) {
s = parent.toString();
}
s += name + "/";
return s;
}
public Bookshelf getBookshelf() {
return bookshelf;
}
public void setBookshelf(Bookshelf bookshelf) {
this.bookshelf = bookshelf;
}