这里我有一个包含多名学生和多位老师的XML文件:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<users>
<students>
<student id="student1">
<name>Alan</name>
<age>11</age>
<dob>01/01/2001</dob>
<grade>A+</grade>
</student>
<student id="student2">
<name>Bob</name>
<age>22</age>
<dob>02/02/2002</dob>
<grade>A</grade>
</student>
</students>
<teachers>
<teacher id="teacher3">
<name>David</name>
<age>33</age>
<dob>03/03/2003</dob>
<subject>Maths</subject>
</teacher>
<teacher id="teacher4">
<name>Ellen</name>
<age>44</age>
<dob>04/04/2004</dob>
<subject>English</subject>
</teacher>
</teachers>
</users>
我有一个Java应用程序,可以正常读取此文件。然而,就写作而言,它是一个混乱的混乱。它与应用程序在读取和写入名称/年龄/ dob时的行为一致,但在我尝试写入成绩/主题的那一刻,它失去了控制权。
我通过打印列表中每个项目的名称来测试它;并按预期打印:
我通过打印列表中每个项目的年龄来再次测试;再次,它按预期打印:
但是这次,我尝试打印主题:
在打印第一位老师后打印学生下的科目并打破,我试图了解原因。因此,对于我的最终测试,我决定打印索引0处的所有元素,包括成绩和主题,看看会发生什么:
主题应该在索引2,而不是0,那么为什么这样做呢?为什么系统读取和写入正确直到这一点?只是包装,这是我的XSD,用于在读取之前验证XML。
<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'>
<xs:element name="users">
<xs:complexType>
<xs:sequence>
<xs:element ref="students" minOccurs='1' maxOccurs='unbounded'/>
<xs:element ref="teachers" minOccurs='1' maxOccurs='unbounded'/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="students">
<xs:complexType>
<xs:sequence>
<xs:element ref="student" minOccurs='1' maxOccurs='unbounded'/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="student">
<xs:complexType>
<xs:sequence>
<xs:element ref="name" minOccurs='0' maxOccurs='1'/>
<xs:element ref="age" minOccurs='0' maxOccurs='1'/>
<xs:element ref="dob" minOccurs='0' maxOccurs='1'/>
<xs:element ref="grade" minOccurs='0' maxOccurs='1'/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="teachers">
<xs:complexType>
<xs:sequence>
<xs:element ref="teacher" minOccurs='1' maxOccurs='unbounded'/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="teacher">
<xs:complexType>
<xs:sequence>
<xs:element ref="name" minOccurs='0' maxOccurs='1'/>
<xs:element ref="age" minOccurs='0' maxOccurs='1'/>
<xs:element ref="dob" minOccurs='0' maxOccurs='1'/>
<xs:element ref="subject" minOccurs='0' maxOccurs='1'/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="name" type='xs:string'/>
<xs:element name="age" type='xs:string'/>
<xs:element name="dob" type='xs:string'/>
<xs:element name="grade" type='xs:string'/>
<xs:element name="subject" type='xs:string'/>
</xs:schema>
void updateXML(int index, String fields[]) {
try {
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.parse(new File(fileName));
doc.getElementsByTagName("name").item(index).setTextContent(fields[0]);
doc.getElementsByTagName("age").item(index).setTextContent(fields[1]);
doc.getElementsByTagName("dob").item(index).setTextContent(fields[2]);
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File(fileName));
transformer.transform(source, result);
} catch (Exception error) {
error.getMessage();
}
}
目前它正常工作,它可以正确保存数据。但由于我遇到的问题,不包括成绩/科目。
这是创建对象的类:
class Model extends DefaultHandler {
String fileName;
ArrayList<User> listOfUsers;
Student student;
Teacher teacher;
boolean blnStudent = false;
boolean blnTeacher = false;
boolean blnName = false;
boolean blnAge = false;
boolean blnDOB = false;
boolean blnGrade = false;
boolean blnSubject = false;
Model() {
fileName = "school.xml";
listOfUsers = new ArrayList<User>();
}
ArrayList<User> getListOfUsers() {
if (validateXML() == true) {
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
parser.parse(new File(fileName), this);
} catch (Exception error) {
error.getMessage();
}
}
return listOfUsers;
}
boolean validateXML() {
try {
SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
Schema schema = factory.newSchema(new File("school.xsd"));
Validator validator = schema.newValidator();
Source source = new StreamSource(new File(fileName));
validator.validate(source);
return true;
} catch (Exception error) {
error.getMessage();
return false;
}
}
public void startElement(String uri, String localName, String tagName, Attributes attributes) throws SAXException {
if (tagName.equalsIgnoreCase("student")) {
student = new Student(attributes.getValue("id"));
blnStudent = true;
} else if (tagName.equalsIgnoreCase("teacher")) {
teacher = new Teacher(attributes.getValue("id"));
blnTeacher = true;
} else if (tagName.equalsIgnoreCase("name")) {
blnName = true;
} else if (tagName.equalsIgnoreCase("age")) {
blnAge = true;
} else if (tagName.equalsIgnoreCase("dob")) {
blnDOB = true;
} else if (tagName.equalsIgnoreCase("grade")) {
blnGrade = true;
} else if (tagName.equalsIgnoreCase("subject")) {
blnSubject = true;
}
}
public void endElement(String uri, String localName, String tagName) throws SAXException {
if (tagName.equalsIgnoreCase("student")) {
listOfUsers.add(student);
} else if (tagName.equalsIgnoreCase("teacher")) {
listOfUsers.add(teacher);
}
}
public void characters(char ch[], int start, int length) throws SAXException {
if (blnStudent) {
if (blnName) {
student.setName(new String(ch, start, length));
blnName = false;
} else if (blnAge) {
student.setAge(new String(ch, start, length));
blnAge = false;
} else if (blnDOB) {
student.setDOB(new String(ch, start, length));
blnDOB = false;
} else if (blnGrade) {
student.setGrade(new String(ch, start, length));
blnGrade = false;
blnStudent = false;
}
} else if (blnTeacher) {
if (blnName) {
teacher.setName(new String(ch, start, length));
blnName = false;
} else if (blnAge) {
teacher.setAge(new String(ch, start, length));
blnAge = false;
} else if (blnDOB) {
teacher.setDOB(new String(ch, start, length));
blnDOB = false;
} else if (blnSubject) {
teacher.setSubject(new String(ch, start, length));
blnSubject = false;
blnTeacher = false;
}
}
}
void updateXML(int index, String fields[]) {
try {
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.parse(new File(fileName));
doc.getElementsByTagName("name") .item(index).setTextContent(fields[0]);
doc.getElementsByTagName("age") .item(index).setTextContent(fields[1]);
doc.getElementsByTagName("dob") .item(index).setTextContent(fields[2]);
// IF STUDENT
doc.getElementsByTagName("grade") .item(index).setTextContent(fields[3]);
// ELSE TEACHER
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File(fileName));
transformer.transform(source, result);
} catch (Exception error) {
error.getMessage();
}
}
}
答案 0 :(得分:0)
问题在于这些要素不会影响用户自己;它们只能通过创建它们的数量来调用。例如,当我设置用户名时:
doc.getElementsByTagName("name").item(0).setTextContent("Alan Zero");
我不是要求系统set the FIRST USER'S name value
,我要求系统做的是set the FIRST NAME value
。因此,只要每个用户创建完全相同数量的字段,这就不会有问题,因为每个字段都会自动分配给各自的用户。例如:
如果他们每个人都有成绩:
但是在我的示例中,某些用户可以拥有成绩值,而某些用户可以拥有主题值。结果,索引值变得不一致。例如:
因此,等级/主题值将被编入索引:
和
为了纠正这个问题,我需要找到一种方法来分别绑定每个元素。谢谢大家的快速回复。