当前位置: 首页 > 知识库问答 >
问题:

如何使用java读取XML文件

刘浩思
2023-03-14

我试图从XML文件中读入一些数据,但遇到了一些问题,我的XML如下所示:

 <Tree>
  <child>
   <Property Name="id"/>
   <Property Name="username">abc</Property>
   <Property Name="phoneType">phone1</Property>
   <Property Name="value">123456</Property>
   </child>
   <child>
   <Property Name="id"/>
   <Property Name="username">def</Property>
   <Property Name="phoneType">phone2</Property>
   <Property Name="value">6789012</Property>
   </child>
   </Tree>

我试图将这些值作为字符串读入Java程序,到目前为止,我已经编写了以下代码:

File fXmlFile = new File("C:\\Users\\welcome\\Downloads\\ta\\abc.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
doc.getDocumentElement().normalize();

System.out.println("Root element :" + doc.getDocumentElement().getNodeName());
NodeList nList = doc.getElementsByTagName("child");
System.out.println("----------------------------");

for (int temp = 0; temp < nList.getLength(); temp++) {
    Node nNode = nList.item(temp);
    System.out.println("\nCurrent Element :" + nNode.getNodeName());
    if (nNode.getNodeType() == Node.ELEMENT_NODE) {
        Element eElement = (Element) nNode;
        System.out.println("id id : "
                           + eElement.getAttribute("id"));

我正在努力读取和打印id、用户名等的值。

共有3个答案

吴凯泽
2023-03-14

无论如何,读取XML文件都不是一件小事。它要求读者对文件的结构有深入的了解。我的意思是,元素名称、属性名称、属性的数据类型、元素的顺序、元素是简单的还是复杂的(意味着它们是平面的还是下面有嵌套的元素)。

如Jon Skeet的评论所示,一种解决方案是使用Java文档API。此接口具有从XML文件获取数据所需的所有方法。然而,在我看来,这仍然给读者留下了知道元素和属性名称的任务。

如果给定XML的XML模式(XSD)或文档类型定义(DTD)可用或易于构造,我更喜欢使用许多库中的一个来解析XML内容;举几个例子:StaX、JDOM、DOM4j、JAXB。因为我已经广泛使用了它,所以我更喜欢JAXB。JAXB有一些限制,但这些限制超出了本文讨论的范围。值得一提的是,JAXB包含在Java6到10的Java发行版中。在这些版本之外,您必须自己下载JAXB发行版。

我使用JAXB的主要原因之一是,我可以使用POJO中的注释根据现有XML构造类,而无需构建模式。当然,这并不总是简单的。它几乎总是根据模式编译JAXB类。因为这将为XML文档生成Java自定义类,所以您可以通过元素的getter方法调用元素和属性,而不是让读者知道元素名称。

我使用OPs XML文件使用XML复制编辑器生成模式。结果架构如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
  <xs:element name="Tree">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="child" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="child">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="Property" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="Property">
    <xs:complexType mixed="true">
      <xs:attribute name="Name" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
</xs:schema>

一旦有了这个模式,就可以使用Java附带的XJC编译器来编译JAXB类。下面是一个关于如何编译JAXB类的示例:https://docs.oracle.com/javase/tutorial/jaxb/intro/examples.html

要下载JAXB编译器,请转到https://javaee.github.io/jaxb-v2/然后单击“下载独立发行版”。您可以将ZIP文件的内容放在计算机上的任何位置。然后,只需在您的环境变量上设置JAXB_HOME,就可以了。这似乎是一个很大的工作,但到目前为止,这些都是一次性的活动。好处是,当您设置好环境时,编译所有类需要几秒钟的时间;即使您需要基于XML生成模式。

执行编译器生成的树。java子级。java属性。java

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "child"
})
@XmlRootElement(name = "Tree")
public class Tree {

    @XmlElement(required = true)
    protected List<Child> child;

    public List<Child> getChild() {
        if (child == null) {
            child = new ArrayList<Child>();
        }
        return this.child;
    }
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "property"
})
@XmlRootElement(name = "child")
public class Child {

    @XmlElement(name = "Property", required = true)
    protected List<Property> property;

    public List<Property> getProperty() {
        if (property == null) {
            property = new ArrayList<Property>();
        }
        return this.property;
    }
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "content"
})
@XmlRootElement(name = "Property")
public class Property {

    @XmlValue
    protected String content;
    @XmlAttribute(name = "Name", required = true)
    protected String name;

    public String getContent() {
        return content;
    }

    public void setContent(String value) {
        this.content = value;
    }

    public String getName() {
        return name;
    }

    public void setName(String value) {
        this.name = value;
    }
}

读取过程(解组)将XML文件转换为这些生成的数据类型。JAXB解组过程使用JAXBContext实用程序类创建解组器,然后调用散集方法将XML文件转换为对象:

JAXBContext context = JAXBContext.newInstance(Tree.class); // the argument is the root node
Tree xmlDoc = (Tree) context.createUnmarshaller().unmarshal(new FileReader("abc.xml")); // Reads the XML and returns a Java object

要编写,您将使用Java类存储数据并创建结构。在这种情况下,您需要创建所需的属性对象、属性元素的子容器以及作为节点的根节点。您可以一次添加一个元素,也可以创建元素列表,然后一次添加所有元素。填充根节点对象后,只需将其传递给封送拆收器。。。

JAXBContext context = JAXBContext.newInstance(Tree.class);
Marshaller mar= context.createMarshaller();
mar.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); // formatting the xml file
mar.marshal(tree, new File("abc.xml")); // saves the "Tree" object as "abc.xml"
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.List;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;

public class JAXBDemo {
    public static void main(String[] args) {
        try {
            // write
            Tree tree = new Tree();
            Property prop0 = new Property();
            prop0.setName("id");
            prop0.setContent("");
            
            Property prop1 = new Property();
            prop1.setName("username");
            prop1.setContent("abc");
            
            Property prop2 = new Property();
            prop2.setName("phoneType");
            prop2.setContent("phone1");

            Property prop3 = new Property();
            prop3.setName("value");
            prop3.setContent("123456");

            List<Property> props1 = List.of(prop0, prop1, prop2, prop3);

            Property prop4 = new Property();
            prop4.setName("id");
            prop4.setContent("");
            
            Property prop5 = new Property();
            prop5.setName("username");
            prop5.setContent("def");
            
            Property prop6 = new Property();
            prop6.setName("phoneType");
            prop6.setContent("phone2");

            Property prop7 = new Property();
            prop7.setName("value");
            prop7.setContent("6789012");

            List<Property> props2 = List.of(prop4, prop5, prop6, prop7);
            
            Child child1 = new Child();
            Child child2 = new Child();
            
            child1.getProperty().addAll(props1);
            child2.getProperty().addAll(props2);
            
            tree.getChild().add(child1);
            tree.getChild().add(child2);

            JAXBContext context = JAXBContext.newInstance(Tree.class);
            Marshaller mar= context.createMarshaller();
            mar.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
            mar.marshal(tree, new File("abc.xml"));

            // read
            Tree xmlDoc = (Tree) context.createUnmarshaller().unmarshal(new FileReader("abc.xml"));
            List<Child> children = xmlDoc.getChild();
            int i = 1;
            for (Child child : children) {
                System.out.println("Property " + i++ + ":");
                List<Property> props = child.getProperty();
                for (Property prop : props) {
                    System.out.println("Name: " + prop.getName() + "; Content: " + prop.getContent());
                }
            }
        } catch (JAXBException | FileNotFoundException e) {

            e.printStackTrace();
        }
    }
}

为了让它工作,我必须对发行版进行一些“修复”。第一个修复是编辑xjc。bat根据这篇文章:https://github.com/eclipse-ee4j/jaxb-ri/issues/1321.滚动到底部以查看我应用的修复。

然后,我需要将我的“jaxb-runtime”依赖更新到版本2.3.3,以便项目能够与“jaxb-api”版本2.3.1一起工作。

步衡
2023-03-14

可以使用XPath运行完全不同的查询。

File fXmlFile = new File("C:\\Users\\welcome\\Downloads\\ta\\abc.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);

//Get an XPath object and evaluate the expression
XPath xpath = XPathFactory.newInstance().newXPath();
String propertyId = xpath.evaluate("/Tree/child[1]/Property[@name='id']", document);

更有可能的是,您希望循环遍历所有子元素,可以这样做

NodeList children = (NodeList)xpath.evaluate("/Tree/child", doc, XPathConstants.NODESET);
for (int i=0;i<children.getLength();i++) {
    Element child = (Element)children.get(i);
    String propertyId = child.getAttribute("id");
    ...
}
赵夕
2023-03-14

我建议您使用像jSoup这样的库来读取XML文件,因为您可以从盒子里得到很多功能。

另请阅读:如何使用jsoup解析XML

 类似资料:
  • 问题内容: 我需要使用Java读取XML文件。它的内容就像 是否有特殊的阅读器/ JAR,还是应该使用 FileInputStream进行 阅读? 问题答案: 另一个建议:尝试使用Commons消化器。这使您可以使用基于规则的方法非常快速地开发解析代码。有一个教程在这里和图书馆可在这里 我也同意Brian和Alzoid的观点,因为JAXB非常适合快速启动和运行。您可以使用JDK附带的xjc绑定编译

  • 问题内容: EMF = Eclipse建模框架 我必须在一个课堂项目中使用EMF。我正在尝试了解如何使用EMF执行以下操作: 读取XML, 将值放入对象。 使用ORM将对象中的值持久保存到数据库中。-完成 使用ORM从数据库获取数据并生成XML。 我需要使用EMF(不知道是什么)和JPA(完成)来完成所有这些操作。 我使用过JAXB,我知道,可以使用JAXB完成,但是(EMF == JAXB)怎么

  • 本文向大家介绍java如何解析/读取xml文件,包括了java如何解析/读取xml文件的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了java解析/读取xml文件的方法,供大家参考,具体内容如下 XML文件 Java 代码: 以上就是本文的全部内容,希望对大家的学习有所帮助。

  • 问题内容: 我试图从XML文件中读取一些数据,但遇到麻烦,我拥有的XML如下: 我试图将这些值作为字符串读取到我的Java程序中,到目前为止,我已经编写了以下代码: 我正在努力读取实际的字符串值。 问题答案: 可能的实现之一: 与XML内容一起使用时: 结果并分配给上述和参考。

  • 问题内容: 如何在Java中使用XPath读取XML? 问题答案: 你需要遵循以下要求: 然后,调用传入该代码中定义的文档和所需的返回类型,并将结果转换为结果的对象类型。 如果你需要有关特定XPath表达式的帮助,则可能应该将其作为单独的问题进行询问(除非首先是你的问题-我理解你的问题是如何在Java中使用API​​)。 此XPath表达式将为你提供下第一个URL元素的文本: 这将使你获得第二个:

  • 问题内容: 我想使用Java中的XPath读取XML数据,因此对于我收集的信息,我无法根据需要解析XML。 这是我想做的: 通过其URL从联机获取XML文件,然后使用XPath对其进行解析,我想在其中创建两个方法。一种是输入特定的节点属性ID,然后得到所有的子节点,第二种是假设我只想获得一个特定的子节点值 在上面的示例中,如果我通过@name搜索,我想读取所有元素,并且我想只从@name’Java