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

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

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>

我有一个很大的 xml 文件,我使用 SAX 解析器根据元素标签提取数据,但由于 SAX 解析器不遵循层次结构,每个元素属性或标签都被纯粹地识别并添加到各自的数组列表。

当前输出:

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

reference_id :[100, 200, 100, 400]

当前问题:

我想创建一个方法,当用户输入关键字并能够显示结果时。

例如,如果用户输入项目 1 作为关键字, 我的想法是获取关键字在 name arraylist 中的位置,并从 arraylist 引用 id 中检索相同的位置,因为它是一对一的匹配。所以在这种情况下是 name[0] = reference_id[0]。

但问题是当我将引用 ID 作为关键字进行过滤时。引用 ID 如何告诉它链接到哪个名称?假设如果所有引用 id 都是不同的,就不会有任何问题。但请注意有重复的 id。我应该怎么做?

您可以应用两个概念。

概念 1 使用默认处理程序

您可以使用处理程序解析 XML,因为处理程序处理每个节点,您需要使用开始和结束元素方法构建所需的对象。

我将在名为 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;
  }
}

默认处理程序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;
  }
}

调用所有这些的代码很简单

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

概念 2 XML 使用 XML 文档的路径

NOTE this is NOT SAX

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