Java 在XML标记之间跳转
这在SAX中是个疑问。 我想处理XML文件中的子标记,但前提是它与父标记匹配。 例如:Java 在XML标记之间跳转,java,xml,sax,Java,Xml,Sax,这在SAX中是个疑问。 我想处理XML文件中的子标记,但前提是它与父标记匹配。 例如: <version> <parent tag-1> <tag 1> <tag 2> </parent tag-1 > <parent tag-2> <tag 1> <tag 2> </parent tag-2>
<version>
<parent tag-1>
<tag 1>
<tag 2>
</parent tag-1 >
<parent tag-2>
<tag 1>
<tag 2>
</parent tag-2>
</version>
在上面的代码中,我希望首先匹配父标记(即基于用户输入的父标记-1或父标记``-2),然后才处理它下面的子标记。
记住SAX对DOM的控制有限,而且我是SAX和Java的新手,这可以在SAX解析器中实现吗?如果是的话,你能引用相应的方法吗?
TIA当然,记住父标记可以很容易地完成 通常,在解析xml标记时,人们使用堆栈跟踪这些标记的族映射。您的案例可以通过以下代码轻松解决:
Stack<Tag> tagStack = new Stack<Tag>();
public void startElement(String uri, String localName, String qName,
Attributes attributes)
if(localName.toLowerCase().equals("parent")){
tagStack.push(new ParentTag());
}else if(localName.toLowerCase().equals("tag")){
if(tagStack.peek() instanceof ParentTag){
//do your things here only when the parent tag is "parent"
}
}
}
public void endElement(String uri, String localName, String qName)
throws SAXException{
if(localName.toLowerCase().equals("parent")){
tagStack.pop();
}
}
但是我更喜欢堆栈方式,因为它可以跟踪所有祖先标记。当然,记住父标记可以很容易地完成 通常,在解析xml标记时,人们使用堆栈跟踪这些标记的族映射。您的案例可以通过以下代码轻松解决:
Stack<Tag> tagStack = new Stack<Tag>();
public void startElement(String uri, String localName, String qName,
Attributes attributes)
if(localName.toLowerCase().equals("parent")){
tagStack.push(new ParentTag());
}else if(localName.toLowerCase().equals("tag")){
if(tagStack.peek() instanceof ParentTag){
//do your things here only when the parent tag is "parent"
}
}
}
public void endElement(String uri, String localName, String qName)
throws SAXException{
if(localName.toLowerCase().equals("parent")){
tagStack.pop();
}
}
但是我更喜欢堆栈方式,因为它跟踪所有祖先标记。SAX解析器将在实现中调用方法,每次它碰到一个标记。如果您希望根据父对象的不同而有不同的行为,则必须将其保存到变量中。SAX解析器将在实现中调用方法,每次它碰到标记时。如果您希望根据父对象的不同而有不同的行为,则必须将其保存到变量中。SAX无论如何都要浏览整个文档,如果您考虑这样做是出于性能原因的话 但是,从代码简洁性的角度来看,通过将SAX解析器与。您可能仍然需要自己编写逻辑(类似于中提供的逻辑),但是您可以将其抽象为过滤器实现,而不是将其放在应用程序逻辑中
这将使您更容易地重用过滤逻辑,并且可能会使您的应用程序代码更干净、更易于理解。SAX无论如何都会浏览整个文档,如果您考虑这样做是出于性能原因的话 但是,从代码简洁性的角度来看,通过将SAX解析器与。您可能仍然需要自己编写逻辑(类似于中提供的逻辑),但是您可以将其抽象为过滤器实现,而不是将其放在应用程序逻辑中
这将使您更容易地重用过滤逻辑,并且可能会使您的应用程序代码更干净、更易于理解。如果您想跳转到特定的标记,则需要使用DOM解析器。这将把整个文档读入内存,然后提供访问树的特定节点的各种方法,例如按名称请求标记,然后请求该标记的子节点
因此,如果您不局限于SAX,那么我建议您使用DOM。我认为在DOM上使用SAX的主要原因是DOM需要更多的内存,因为整个文档一次加载。如果要跳转到特定的标记,则需要使用DOM解析器。这将把整个文档读入内存,然后提供访问树的特定节点的各种方法,例如按名称请求标记,然后请求该标记的子节点
因此,如果您不局限于SAX,那么我建议您使用DOM。我认为在DOM上使用SAX的主要原因是DOM需要更多的内存,因为整个文档一次加载。由@Wing C.Chen提出的解决方案非常不错,但在您的情况下,我不会使用堆栈 解析XML时堆栈的用例 堆栈和XML的一个常见用例是,例如,在使用您自己的lexer(即带有容错功能的手工XML解析器)时,验证XML标记是否平衡 一个具体的例子是为EclipseIDE构建XML文档的大纲 何时使用SAX、拉式解析器等
- 解析大型XML文件时的内存效率
- 您不需要在文档中来回导航
- 您希望轻松访问节点
- 您希望随时在文档中来回导航
- 与开发时间/可读性/维护相比,速度不是主要要求
我个人更喜欢Dom4J,但我不介意其他API,比如JDom,甚至是支持XPath的Xpp3。由@Wing C.Chen提出的解决方案非常不错,但在您的情况下,我不会使用堆栈 解析XML时堆栈的用例 堆栈和XML的一个常见用例是,例如,在使用您自己的lexer(即带有容错功能的手工XML解析器)时,验证XML标记是否平衡 一个具体的例子是为EclipseIDE构建XML文档的大纲 何时使用SAX、拉式解析器等
- 解析大型XML文件时的内存效率
- 您不需要在文档中来回导航
- 您希望轻松访问节点