0

我有这个 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;
        }       
}
4

3 回答 3

1

你试过JAXB吗?

“用于 XML 绑定的 Java 架构 (JAXB) 允许 Java 开发人员将 Java 类映射到 XML 表示。”

然后你可以迭代对象。

http://en.wikipedia.org/wiki/Java_Architecture_for_XML_Binding

于 2013-09-03T13:37:54.700 回答
0

下面的例子,将找到第一个包含name内容为 的子元素的元素tim,并打印其nameprimary_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());
}

这可能不是最干净的方法,但它可以完成工作。您可以将大部分内容包装在辅助方法中 - 请注意这两个println语句的相似之处,它们只是在呼唤因式分解。

[编辑]按照评论中的要求更新了示例

于 2013-09-03T14:04:32.130 回答
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类,它包含Contact代表 XML 文件的联系人元素的对象列表:

@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 的好主意。

于 2013-09-03T14:14:45.697 回答