为啥我在解析 XML 时会从此方法中得到重复记录?
Posted
技术标签:
【中文标题】为啥我在解析 XML 时会从此方法中得到重复记录?【英文标题】:Why am I getting duplicate records from this method when I parse XML?为什么我在解析 XML 时会从此方法中得到重复记录? 【发布时间】:2021-11-19 04:30:35 【问题描述】:我正在尝试使用 Stax 解析 XML 中的内容。从它创建一个对象并将其放置在列表中。我为此创建了parseXml()
方法,但如果元素国家有两个以上的元素用户,它总是重复最后一个。
我用的方法是这个:
public static List<User> parseXML()
List<User> empList = new ArrayList<>();
User emp = null;
XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
try
XMLEventReader xmlEventReader = xmlInputFactory.createXMLEventReader(new FileInputStream("C:\\Users\\HP\\Desktop\\untitled1\\src\\main\\xml\\users.xml"));
while(xmlEventReader.hasNext())
XMLEvent xmlEvent = xmlEventReader.nextEvent();
if (xmlEvent.isStartElement())
StartElement startElement = xmlEvent.asStartElement();
if(startElement.getName().getLocalPart().equals("country"))
emp = new User();
//Get the 'id' attribute from Employee element
Attribute idAttr = startElement.getAttributeByName(new QName("name"));
if(idAttr != null)
emp.setCountry(idAttr.getValue());
//set the other varibles from xml elements
else if(startElement.getName().getLocalPart().equals("first_name"))
xmlEvent = xmlEventReader.nextEvent();
emp.setFirst_name(xmlEvent.asCharacters().getData());
else if(startElement.getName().getLocalPart().equals("last_name"))
xmlEvent = xmlEventReader.nextEvent();
emp.setLast_name(xmlEvent.asCharacters().getData());
else if(startElement.getName().getLocalPart().equals("address"))
xmlEvent = xmlEventReader.nextEvent();
emp.setAddress(xmlEvent.asCharacters().getData());
else if(startElement.getName().getLocalPart().equals("city"))
xmlEvent = xmlEventReader.nextEvent();
emp.setCity(xmlEvent.asCharacters().getData());
else if(startElement.getName().getLocalPart().equals("email"))
xmlEvent = xmlEventReader.nextEvent();
emp.setEmail(xmlEvent.asCharacters().getData());
//if Employee end element is reached, add employee object to list
if(xmlEvent.isEndElement())
EndElement endElement = xmlEvent.asEndElement();
if(endElement.getName().getLocalPart().equals("user"))
empList.add(emp);
catch (FileNotFoundException | XMLStreamException e)
e.printStackTrace();
return empList;
这里是 XML:
<data>
<continent name="Europe">
<country name="United Kingdom">
<!-- Users -->
<user>
<first_name>John</first_name>
<last_name>Smith</last_name>
<address>320 Regent Street</address>
<city>London</city>
<email>john.smith@gmail.com</email>
<password>skek3E5k</password>
</user>
<user>
<first_name>Michael</first_name>
<last_name>Smith</last_name>
<address>322 Regent Street</address>
<city>London</city>
<email>michael.smith@hotmail.com</email>
<password>gk3288skW</password>
</user>
</country>
<country name="Germany">
<!-- Users -->
<user>
<first_name>Max</first_name>
<last_name>Mustermann</last_name>
<address>Berlinerstrasse 7</address>
<city>Hamburg</city>
<email>mmustermann@yahoo.com</email>
<password>kdkei44229</password>
</user>
</country>
</continent>
<continent name="North America">
<country name="United States">
<!-- Users -->
<user>
<first_name>Julia</first_name>
<last_name>Johnson</last_name>
<address>300 Boylston Ave E</address>
<city>Seattle</city>
<email>julia.johnson@gmail.com</email>
<password>49dksSSe3</password>
</user>
</country>
</continent>
</data>
我的方法做错了什么?
【问题讨论】:
【参考方案1】:只有在遇到<country>
时才创建User
的实例,但每个国家/地区可能有多个用户。您最终会为该国家/地区的每个用户添加相同的 User
对象。
我认为混淆可能来自这样一个事实,即您实际上是将emp
的引用添加到您的empList
— 因此,当您为给定国家/地区的第二个、第三个等用户更改emp
时,您更改列表中已存在的同一 User
对象。
您可能应该在每次遇到<user>
标记时创建您的User
对象。但是,这将要求您还存储当前国家/地区。您的代码可能如下所示:
public static List<User> parseXML()
List<User> empList = new ArrayList<>();
User emp = null;
XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
try
XMLEventReader xmlEventReader = xmlInputFactory.createXMLEventReader(new FileInputStream("C:\\Users\\HP\\Desktop\\untitled1\\src\\main\\xml\\users.xml"));
String country = null;
while(xmlEventReader.hasNext())
XMLEvent xmlEvent = xmlEventReader.nextEvent();
if (xmlEvent.isStartElement())
StartElement startElement = xmlEvent.asStartElement();
if(startElement.getName().getLocalPart().equals("country"))
//Get the 'id' attribute from Employee element
Attribute idAttr = startElement.getAttributeByName(new QName("name"));
if(idAttr != null)
country = idAttr.getValue();
else if (startElement.getName().getLocalPart().equals("user"))
emp = new User();
emp.setCountry(country);
//set the other varibles from xml elements
else if(startElement.getName().getLocalPart().equals("first_name"))
xmlEvent = xmlEventReader.nextEvent();
emp.setFirst_name(xmlEvent.asCharacters().getData());
else if(startElement.getName().getLocalPart().equals("last_name"))
xmlEvent = xmlEventReader.nextEvent();
emp.setLast_name(xmlEvent.asCharacters().getData());
else if(startElement.getName().getLocalPart().equals("address"))
xmlEvent = xmlEventReader.nextEvent();
emp.setAddress(xmlEvent.asCharacters().getData());
else if(startElement.getName().getLocalPart().equals("city"))
xmlEvent = xmlEventReader.nextEvent();
emp.setCity(xmlEvent.asCharacters().getData());
else if(startElement.getName().getLocalPart().equals("email"))
xmlEvent = xmlEventReader.nextEvent();
emp.setEmail(xmlEvent.asCharacters().getData());
//if Employee end element is reached, add employee object to list
if(xmlEvent.isEndElement())
EndElement endElement = xmlEvent.asEndElement();
if(endElement.getName().getLocalPart().equals("user"))
empList.add(emp);
catch (FileNotFoundException | XMLStreamException e)
e.printStackTrace();
return empList;
【讨论】:
以上是关于为啥我在解析 XML 时会从此方法中得到重复记录?的主要内容,如果未能解决你的问题,请参考以下文章
为啥在使用 kotlin 将数据添加到 firebase 实时数据库时会得到重复值?
mybatis中查询时会将查询改成select count,这是为啥
为啥我在使用 pip install 命令时会收到此错误 [重复]