我在XML解析方面遇到了一些问题。
我正在创建一个函数,其中参数是XML文件中的某个“元素”。 找到后,我想返回root属性的值。 这是我的代码:
FileInputStream file = new FileInputStream(new File("C:\\Users\\Grizzly\\Java\\Projet_16_17-20161214\\bdd.xml"));
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(file);
doc.getDocumentElement().normalize();
NodeList nList = doc.getElementsByTagName("type");
for (int temp = 0; temp < nList.getLength(); temp++)
{
Node nNode = nList.item(temp);
if(nNode.toString().equalsIgnoreCase(element))
{
Element eElement = (Element) nNode;
System.out.println("Taxe= "+ eElement.getAttribute("taxe"));
}
}
}
有关如何做到这一点的任何想法? 这是我的XML文件:
<?xml version="1.0"?>
-<types>
-<type id="Nourriture" taxe="0.1">
<element>pomme</element>
<element>fraise</element>
<element>fromage</element>
<element>viande rouge </element>
</type>
-<type id="Matiere Premiere" taxe="0.2">
<element>fer</element>
<element>polypropylene</element>
</type>
-<type id="Element Solide" taxe="0.3">
<element>voiture</element>
<element>planche surf</element>
<element>pistolet</element>
</type>
</types>
在我的代码中,我尝试从节点列表中获取某个节点的元素,然后将其与用户输入的字符串“element”进行比较,如果它们匹配,则会检查属性值与之相关的税收。
提前致谢。
编辑:我越来越接近我需要的东西了:NodeList nList = doc.getElementsByTagName("type");
for (int temp = 0; temp < nList.getLength(); temp++)
{
Node nNode = nList.item(temp);
NodeList nChildren = nNode.getChildNodes();
Element eElement = (Element) nNode;
for(int i = 0; i < nChildren.getLength(); i++)
{
String onElement = eElement.getElementsByTagName("element").item(i).getTextContent();
if(onElement.equalsIgnoreCase(element))
{
System.out.println("id : " + eElement.getAttribute("id"));
System.out.println("taxe : " + eElement.getAttribute("taxe"));
break;
}
}
}
但它只是阅读第一个元素......并且项目(i)不起作用。 有什么想法吗?
答案 0 :(得分:1)
如果我理解正确,您正在尝试获取具有至少一个具有特定名称(id
)的子元素的所有文档节点的特定属性(taxe
和element
)
虽然问题可以通过迭代DOM并保持状态来解决,但我宁愿将此任务委托给XPath。使用XPath的代码看起来更干净,更易于维护。例如,为了获取具有属性id
和taxe
以及子元素element
的所有元素,您可以使用类似//*[@id and @taxe element]
的XPath表达式。匹配节点在一行中获取。您可以简单地迭代节点并收集属性,如以下示例所示。
示例强>
public static void main(String args[]) {
String element = args.length > 0 ? args[0] : "element";
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder builder = factory.newDocumentBuilder();
FileInputStream file = new FileInputStream(new File("/some/file.xml"));
Document doc = builder.parse(file);
XPath xPath = XPathFactory.newInstance().newXPath();
String expression = "//*[@id and @taxe and " + element + "]";
NodeList nodeList = (NodeList) xPath.compile(expression)
.evaluate(doc, XPathConstants.NODESET);
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
NamedNodeMap attributes = node.getAttributes();
for (int j = 0; j < attributes.getLength(); j++) {
Node aNode = attributes.item(j);
System.out.printf(
"%s: %s\n",
aNode.getNodeName(),
aNode.getNodeValue()
);
}
}
} catch (Exception e) {
System.err.println(e.getMessage());
System.exit(1);
}
}
示例输出
id: Nourriture
taxe: 0.1
id: Matiere Premiere
taxe: 0.2
id: Element Solide
taxe: 0.3
注意,上面的示例打印了父元素的所有属性。如果你只想打印特定的,你可以显然添加一个简单的检查:
String aName = aNode.getNodeName();
if (aName.equals("taxe")) { // ...
但您实际上可以使用XPath过滤掉属性:
String expression = "//*[ " + element + "]/@*[name() = 'id' or name() = 'taxe']";
NodeList nodeList = (NodeList) xPath.compile(expression)
.evaluate(doc, XPathConstants.NODESET);
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
System.out.printf("%s: %s\n", node.getNodeName(), node.getNodeValue());
}
上面的XPath表达式获取名称等于id
或taxe
的所有属性节点。如果您想要所有属性,只需删除最后一个条件:
String expression = "//*[ " + element + "]/@*";