简体   繁体   English

如何在SAX解析器中对具有与父标签的相似属性ID的元素进行分组[Java]

[英]How to group elements with similar attribute id of the parent tag in SAX parser [Java]

Sample of the xml: xml样本:

<name>item1</name>
<reference_id>100</reference_id> -->notice of the duplicate reference id

<name>item 2</name>
<reference_id>200</reference_id>

<name>item 3</name>
<reference_id>100</reference_id> -->notice of the duplicate reference id

<name>item 4</name>
<reference_id>400</reference_id>

I have a large xml file which I use SAX Parser to extract data according to the element tag but since SAX Parser does not follow hierachy and each element attribute or tag is purely identified and added in the respective arraylist. 我有一个很大的xml文件,我使用SAX Parser根据元素标签提取数据,但是由于SAX Parser不会遵循层次结构,并且每个元素属性或标签都被完全标识并添加到相应的arraylist中。

Current Output: 电流输出:

name: [item 1, item 2, item 3, item 4]

reference_id :[100, 200, 100, 400]

Current Problem: 当前问题:

I want to create a method when user inputs a keyword and is able to display the result. 我想在用户输入关键字并能够显示结果时创建一个方法。

Eg if user enters item 1 as the keyword, my idea is to get the position of the keyword in name arraylist and retreive the same position from arraylist reference id since it is one to one match. 例如,如果用户输入第1项作为关键字,我的想法是获取关键字在名称arraylist中的位置,并从arraylist参考ID中检索相同位置,因为它是一对一匹配。 So in this case is name[0] = reference_id[0]. 因此,在这种情况下,名称为[0] = reference_id [0]。

But the problem is when I do a filtering of the reference id as keyword. 但是问题是当我对参考ID作为关键字进行过滤时。 How can reference id tells which name it is linked to? 参考ID如何分辨链接到的名称? Supposely if all reference id is distinct, there should not have any problem. 假设所有参考ID都是唯一的,则应该没有任何问题。 But notice there is duplicated id. 但是请注意,有重复的ID。 How should I go about doing it? 我应该怎么做呢?

There are two concepts you can apply for this. 您可以应用两个概念。

Concept 1 use a Default Handler 概念1使用默认处理程序

You can parse your XML using a handler, as the handler process each node you will need to build the objects you want using the start and end element methods. 您可以使用处理程序来解析XML,因为处理程序处理需要使用start和end元素方法构建所需对象的每个节点。

The object I will store the data in called Name 我将数据存储在名为Name的对象中

public class Name
{
  private String name = null;
  private String value = null;

  public String getName()
  {
    return name;
  }

  public void setName(String name)
  {
    this.name = name;
  }

  public String getValue()
  {
    return value;
  }

  public void setValue(String value)
  {
    this.value = value;
  }
}

The default handler class 默认处理程序类

public class NameHandler extends DefaultHandler
{
  private ArrayList<Name> nameList;
  private Name name = null;
  private boolean nameTag = false;
  private boolean valueTag = false;


  @Override
  public void startElement(String uri, String localName, String qName, Attributes attributes)
          throws SAXException
  {

    if (qName.equalsIgnoreCase("name"))
    {
      name = new Name();
      nameTag = true;
    }
    if (qName.equalsIgnoreCase("reference_id"))
    {
      valueTag = true;
    }
  }

  @Override
  public void endElement(String uri, String localName, String qName) throws SAXException
  {
    if (qName.equalsIgnoreCase("name"))
    {
      //add Name object to list
      nameList.add(name);         
    }
  }

  @Override public void characters(char[] ch, int start, int length) throws SAXException
  {
    String theValue = new String(ch, start, length);
    if (nameTag)
    {
      name.setName(theValue);
      nameTag = false;
    }
    if (valueTag)
    {
      name.setValue(theValue);
      valueTag= false;
    }
  }

  public ArrayList<Name> getNameList()
  {
    return nameList;
  }
}

the code to call all of this is simply 调用所有这些的代码很简单

SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
SAXParser saxParser = saxParserFactory.newSAXParser();
NameHandler handler = new NameHandler();
saxParser.parse(XML,handler);

Concept 2 XML Path using a XML Document 使用XML文档的概念2 XML路径

NOTE this is NOT SAX 注意这不是SAX

The XML path can be built and supped by the input being XML路径可以通过输入来构建和支持

String expression = "/root[name='item 2']/reference_id";

NodeList nodeList = (NodeList) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODESET);
for (int i = 0; i < nodeList.getLength(); i++) {
   System.out.println(nodeList.item(i).getFirstChild().getNodeValue()); 
}

Note completely untested code 注意完全未经测试的代码

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM