我想解析动态生成的xml,它没有xml文件的任何预定义结构。我的Xml看起来像,
<?xml version="1.0" encoding="UTF-8"?>
<metadata>
<control for="9bd2f8fd2421eb0b0a410feaa1f482c50551486a" name="first-name" type="input" datatype="string">
<resources lang="en">
<label>First Name</label>
<help />
<hint>Your first or given name
</hint>
<alert />
</resources>
<resources lang="fr">
<label>Prénom</label>
<help />
<hint>
Votre prénom
</hint>
<alert />
</resources>
<value>Rahul</value>
</control>
<control for="9bd2f8fd2421eb0b0a410feaa1f482c50551486b" name="last-name" type="input" datatype="string">
<resources lang="en">
<label>Last Name</label>
<help />
<hint>Your last name
</hint>
<alert />
</resources>
<resources lang="fr">
<label>Prénom</label>
<help />
<hint>
Votre prénom
</hint>
<alert />
</resources>
<value>Sharma</value>
</control>
</metadata>
从上面的xml我需要获得以下细节,控制器标签中的Name属性以及标签和值标签的内容。所以我尝试了如下,
FileInputStream fis = new FileInputStream("test.xml");
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(fis);
Node objects = doc.getDocumentElement();
for (Node object = objects.getFirstChild(); object != null; object = object.getNextSibling()) {
if (object instanceof Element) {
Element e = (Element)object;
System.out.println(e.getTagName());
if (e.getTagName().equalsIgnoreCase("control")) {
String name = e.getAttribute("name");
System.out.println("It's a " + name + " control!");
}
else {
System.out.println("I don't know what a " + e.getTagName() + " is for.");
}
}
}
使用上面的代码,我可以在controller标签中获取name属性。现在我如何获得标签和价值标签的内容。
我需要以下输出,
name: first-name
label: First Name
value: Rahul
name: last-name
label: Last Name
value: Sharma
答案 0 :(得分:1)
您当前的代码仅通过控件元素进行迭代(因为您正在使用getFirstChild, getNextSibling()
),因此一旦在控件元素“内部”,您需要检索其正确的后代(标签和值)。一种方法是通过调用getElementsByTagName作为标签和值。
if (e.getTagName().equalsIgnoreCase("control")) {
String name = e.getAttribute("name");
System.out.println("It's a " + name + " control!");
NodeList labels = e.etElementsByTagName("label");
for (int i = 0;i<labels.getLength();i++) {
Element labelE = (Element)labels.item(i);
String label = labelE.getTextContent();
//do something with the label content;
}
....
NodeList values = e.etElementsByTagName("value");
Element valueE = (Element)values.item(0); //seems you always have only one value element
String value = valueE.get.getTextContent();
...
}
您的xml有多个资源标签,因此有多个标签,您需要决定如何处理它。例如,您可以首先检索资源标记并检查其lang属性以仅处理EN属性。或者总是拿第一个标签。这取决于你。
答案 1 :(得分:0)
FileInputStream fis = new FileInputStream("test.xml");
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(fis);
NodeList controls = doc.getElementsByTagName("control");
for (int i = 0; i < controls.getLength(); i++) {
Element element = (Element)controls.item(i);
System.out.println(element.getAttribute("name"));
NodeList resources = element.getElementsByTagName("resources");
for (int j = 0; j < resources.getLength(); j++) {
Element resource = (Element) resources.item(j);
System.out.println(resource.getAttribute("lang"));
NodeList contents = resource.getChildNodes();
for (int k = 0; k < contents.getLength(); k++) {
Node item2 = contents.item(k);
if (item2 instanceof Element) {
Element content = (Element)item2;
String tagName = content.getTagName();
if (content.getTextContent() != null && !content.getTextContent().isEmpty()) {
System.out.println(tagName + ":" + content.getTextContent());
}
}
}
}
NodeList values = element.getElementsByTagName("value");
if (values.getLength() > 0) {
Element value = (Element) values.item(0);
System.out.println(value.getTextContent());
}
}
或generante xsd for you xml:
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="metadata">
<xs:complexType>
<xs:sequence>
<xs:element name="control" maxOccurs="unbounded" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="resources" maxOccurs="unbounded" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="label"/>
<xs:element type="xs:string" name="help"/>
<xs:element type="xs:string" name="hint"/>
<xs:element type="xs:string" name="alert"/>
</xs:sequence>
<xs:attribute type="xs:string" name="lang" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element type="xs:string" name="value"/>
</xs:sequence>
<xs:attribute type="xs:string" name="for" use="optional"/>
<xs:attribute type="xs:string" name="name" use="optional"/>
<xs:attribute type="xs:string" name="type" use="optional"/>
<xs:attribute type="xs:string" name="datatype" use="optional"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
使用JAXB命令生成java类:
xjc test.xsd
并将其用于读取值:
JAXBContext context = JAXBContext.newInstance(Metadata.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
Metadata retorno = unmarshaller.unmarshal(new StreamSource(new File("test.xml")), Metadata.class).getValue();
List<Metadata.Control> controls = retorno.getControl();
for (Metadata.Control control : controls) {
System.out.println(control.getName());
List<Metadata.Control.Resources> resources = control.getResources();
for (Metadata.Control.Resources resource : resources) {
System.out.println(resource.getLabel());
System.out.println(resource.getHint());
}
System.out.println(control.getValue());
}