我有这个xml代码
我希望能够拥有一个扫描仪或其他要求用户输入的对象,然后使用该输入来匹配某个节点并显示该节点以及其下的其余节点。
例如,我想要选择搜索姓名,地址,电子邮件,电话或群组。如果我选择名称,我希望能够输入名称“tim”,然后使用该输入来查找节点并将其与兄弟节点一起显示,但仅针对该特定联系人。
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<contactInfo>
<contact>
<name>tim</name>
<primary_address>1111 virginia road</primary_address>
<secondary_address>N/A</secondary_address>
<primary_email>asdf@gmail.com</primary_email>
<backup_email1>N/A</backup_email1>
<backup_email2>N/A</backup_email2>
<primary_phone>703-111-1111</primary_phone>
<backup_phone1>N/A</backup_phone1>
<backup_phone2>N/A</backup_phone2>
<group1>family</group1>
<group2>friends</group2>
</contact>
<contact>
<name>john</name>
<primary_address>1111 pike road</primary_address>
<secondary_address>N/A</secondary_address>
<primary_email>john@gmail.com</primary_email>
<backup_email1>N/A</backup_email1>
<backup_email2>N/A</backup_email2>
<primary_phone>222-222-2222</primary_phone>
<backup_phone1>N/A</backup_phone1>
<backup_phone2>N/A</backup_phone2>
<group1>friends</group1>
<group2>N/A</group2>
</contact>
<contact>
<name>Tim Calara</name>
<primary_address>1234 Wallaby Way</primary_address>
<secondary_address>N/A</secondary_address>
<primary_email>tim@gmail.com</primary_email>
<backup_email1>N/A</backup_email1>
<backup_email2>N/A</backup_email2>
<primary_phone>111-123-4567</primary_phone>
<backup_phone1>N/A</backup_phone1>
<backup_phone2>N/A</backup_phone2>
<group1>family</group1>
<group2>friends</group2>
</contact>
</contactInfo>
这是我的代码的搜索部分,如果您需要我的整个代码,请告诉我(整个过程非常冗长)。
public void search() throws SAXException, IOException, ParserConfigurationException, XPathExpressionException
{
System.out.println("\nSearch for Contact");
int choice = searchMenu ( );
switch (choice)
{
case 1:
try
{
File file = new File("/Users/T/Eclipse Workspace/contactInfo/nData.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document xmlDocument = dBuilder.parse(file);
XPath xPath = XPathFactory.newInstance().newXPath();
System.out.println("Please enter Contact name: ");
String input = kbd.nextLine();
String expression = "/contactInfo/contact[name() = "input"]";
System.out.println(expression);
Node node = (Node) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODE);
if(null != node) {
NodeList nodeList = node.getChildNodes();
for (int i = 0;null!=nodeList && i < nodeList.getLength(); i++) {
Node nod = nodeList.item(i);
if(nod.getNodeType() == Node.ELEMENT_NODE)
System.out.println(nodeList.item(i).getNodeName() + " : " + nod.getFirstChild().getNodeValue());
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
break;
//case 2:
//case 3: email ( ); break;
//case 4: phone ( ); break;
//case 5: break;
//case 6: exit (); break;
}
}
答案 0 :(得分:1)
你试过JAXB吗?
“用于XML绑定的Java体系结构(JAXB)允许Java开发人员将Java类映射到XML表示。”
然后你可以迭代对象。
http://en.wikipedia.org/wiki/Java_Architecture_for_XML_Binding
答案 1 :(得分:0)
以下示例将找到包含内容为name
的{{1}}子项的第一个元素,并打印其tim
和name
元素的内容:
primary_address
这可能不是最干净的方式,但它确实起到了作用。你可以将大部分内容包装在辅助方法中 - 注意两个Document doc = getDocument();
XPath xpath = XPathFactory.newInstance().newXPath();
NodeList nodeList;
nodeList = (NodeList) xpath.evaluate("//name[.='tim']/..", doc, XPathConstants.NODESET);
for(int i = 0; i < nodeList.getLength(); i++) {
Node contact = nodeList.item(i);
System.out.println("Name: " + ((Node)xpath.evaluate("name", contact, XPathConstants.NODE)).getTextContent());
System.out.println("Address: " + ((Node)xpath.evaluate("primary_address", contact, XPathConstants.NODE)).getTextContent());
}
语句的相似程度,它们只是为了分解而烦恼。
[EDIT]根据评论中的要求更新了示例
答案 2 :(得分:0)
以下是使用JAXB将XML表示映射到Java类的方法:在给定的XML中,ContactInfo
元素包含contact
个子元素的列表。如果您将ContactInfo
和Conatct
表示为Java对象,ContactInfo
将包含Contact
个实例的列表。下面是实现此目的的示例代码:
创建Contact
类:
@XmlRootElement
public class Contact{
private String name;
private String primaryAddress;
//other properties
// getters and setters
}
这是ContactInfo
类,其中包含表示XML文件的联系元素的Contact
个对象列表:
@XmlRootElement
public class ContactInfo {
private List<Contact> contactList;
public List<Contact> getContactList() {
return contactList;
}
@XmlElementWrapper(name = "ContactList")
@XmlElement(name = "Contact")
public void setCustomerList(List<Contact> contactList) {
this.contactList =contactList;
}
}
现在,通过使用JAXB,您可以按如下方式读取xml文件:
File file = new File("Path to your xml file");
JAXBContext jaxbContext = JAXBContext.newInstance(ContactInfo.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
ContactInfo contactInfo = (ContactInfo) unmarshaller.unmarshal(file);
您还可以从ContactInfo
创建xml,如下所示:
//create your "ContactInfo" object with a list of "Contact"s
ContactInfo contactInfo=new ContactInfo();
List<Contact> list=new ArrayList<>();
//add contacts to the list and add the list to ContactInfo
File file = new File("path to save your XML file");
JAXBContext jaxbContext = JAXBContext.newInstance(ContactInfo.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
jaxbMarshaller.marshal(contactInfo, file);
我建议你阅读:Java Architecture for XML Binding以便对API有所了解。