这是SAX的疑问。 我想在XML文件中处理子标记,只要它与父标记匹配。 例如:
<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解析器中完成,请记住SAX对DOM的控制有限,而且我是SAX和Java的新手吗?如果是这样,你能引用相应的方法吗? TIA
答案 0 :(得分:1)
当然,可以通过记住父标签轻松完成。
通常,在解析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();
}
}
或者您可以通过更新标记名来简单地记住您处于什么标记中:
String tagName = null;
public void startElement(String uri, String localName, String qName,
Attributes attributes)
if(localName.toLowerCase().equals("parent")){
tagName = "parent";
}else if(localName.toLowerCase().equals("tag")){
if(tagName!= null && tagName.equals("parent")){
//do your things here only when the parent tag is "parent"
}
}
}
public void endElement(String uri, String localName, String qName)
throws SAXException{
tagName = null;
}
但我更喜欢堆叠方式,因为它会跟踪你所有的祖先标签。
答案 1 :(得分:1)
如果你出于性能原因考虑这样做,那么无论如何,SAX都将打破整个文档。
但是,从代码良好的角度来看,你可以让SAX解析器通过用XMLFilter连接来返回不匹配的子节点。您可能仍然需要自己编写逻辑 - 类似Wing C. Chen's post中提供的逻辑 - 但不是将其放在应用程序逻辑上,而是将其抽象为过滤器实现。
这样可以让您更轻松地重复使用过滤逻辑,这可能会使您的应用程序代码更清晰,更容易理解。
答案 2 :(得分:1)
@Wing C.陈提出的解决方案不仅不错,但在你的情况下,我不会使用堆栈。
解析XML时堆栈的用例
堆栈和XML的常见用例是在使用自己的词法分析器(即具有容错性的手工XML解析器)时验证XML标记是否平衡。
它的一个具体示例是为Eclipse IDE构建XML文档的大纲。
何时使用SAX,拉解析器等
解析大型XML文件时的内存效率
您无需在文档中来回导航。
但是,使用SAX解析复杂文档可能会变得乏味,特别是如果您想根据某些条件将操作应用于节点。
何时使用像APis
这样的DOM您希望轻松访问节点
您希望随时在文档中来回导航
速度不是开发时间/可读性/维护的主要要求
我的推荐
如果您没有庞大的XML,请使用类似API的DOM并使用XPath选择节点。 我个人更喜欢Dom4J,但我不介意其他APis,如JDom,甚至Xpp3都支持XPath。
答案 3 :(得分:0)
每次点击标记时,SAX Parser都会在您的实现中调用一个方法。如果您需要不同的行为,具体取决于父项,则必须将其保存到变量中。
答案 4 :(得分:0)
如果要跳转到特定标记,则需要使用DOM解析器。这会将整个文档读入内存,然后提供访问树的特定节点的各种方法,例如按名称请求标记,然后询问该标记的子项。
因此,如果您不限于SAX,那么我会推荐DOM。我认为使用SAX over DOM的主要原因是DOM需要更多内存,因为整个文档一次加载。