我在 XML 解析方面遇到了一个小问题。
我正在创建一个函数,其中的参数是 XML 文件中的某个“元素”。 找到后,我想返回根属性的值。 这是我的代码:
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”进行比较,如果匹配则检查属性值与之 Hook 的税收。
提前致谢。
编辑:我越来越接近我需要的了:
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;
}
}
}
但它只读取第一个元素...而 item(i) 不工作。 有什么想法吗?
最佳答案
如果我没理解错的话,您正在尝试获取所有文档节点的特定属性(id
和 taxe
),这些节点至少有一个具有特定名称的子元素( 元素
).
虽然问题可以通过迭代 DOM 和保持状态来解决,但我宁愿将此任务委托(delegate)给 XPath。使用 XPath 的代码看起来更简洁,更易于维护。例如,为了获取所有具有属性 id
和 taxe
以及子元素 element
的元素,您可以使用像 这样的 XPath 表达式//*[@id 和@taxe 元素]
。匹配的节点在一行中获取。您可以简单地迭代节点并收集属性,如以下示例所示。
示例
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 + "]/@*";
关于java - XML 解析为 Java - 获取根属性值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41181366/