我正在嘗試從 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、用戶名等的值。
uj5u.com熱心網友回復:
我建議您使用像jsoup這樣的庫來讀取 XML 檔案,因為您可以獲得很多開箱即用的功能。
另請閱讀:如何使用 jsoup 決議 XML
uj5u.com熱心網友回復:
您可以使用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");
...
}
uj5u.com熱心網友回復:
無論如何,讀取 XML 檔案都不是一件容易的事。它要求讀者對檔案的結構有深入的了解。我的意思是,元素名稱是什么,屬性名稱,屬性的資料型別,元素的順序,元素是簡單還是復雜(意味著它們是平面的或下面有嵌套元素)。
如 Jon Skeet 的評論所示,一種解決方案是使用 Java Document API。該介面具有從 XML 檔案獲取資料所需的所有方法。然而,在我看來,這仍然留給讀者了解元素和屬性名稱的任務。
如果給定 XML 的 XML 模式 (XSD) 或檔案型別定義 (DTD) 可用或可以輕松構建,我更喜歡使用眾多庫之一來決議 XML 內容;僅舉幾例 StaX、JDOM、DOM4j、JAXB。因為我已經廣泛使用它,所以我更喜歡 JAXB。JAXB 有一些限制,但這些限制超出了本討論的范圍。值得一提的是,JAXB 包含在 Java 6 到 10 的 Java 發行版中。在這些版本之外,您必須自己下載 JAXB 發行版。
我使用 JAXB 的主要原因之一是我可以在 POJO 中使用注釋來根據現有 XML 構造一個類,而無需構建模式。當然,這并不總是那么簡單。它幾乎總是根據模式編譯您的 JAXB 類。因為這將為您的 XML 檔案生成 Java 自定義類,所以您可以通過它們的 getter 方法將元素稱為屬性,而不是讓讀者知道元素名稱的負擔。
我使用 OPs XML 檔案使用XML Copy Editor生成模式。生成的架構如下所示:
<?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 生成架構。
執行編譯器生成Tree.java,Child.java和Property.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;
}
}
子.java
@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;
}
}
屬性.java
@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實用程式類創建解組器,然后呼叫 unmarshal 方法將 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 類來存盤資料并創建結構。在這種情況下,您將需要創建所需的Property物件、Child屬性元素的容器以及作為節點的Tree根節點。您可以一次添加一個元素,也可以創建一個串列并一次添加所有元素。填充根節點物件后,只需將其傳遞給編組器...
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 版一起使用。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/415624.html
標籤:
上一篇:如何決議xml字串?
下一篇:檢查屬性的空值
