如何在 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
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