XML解析为Java - 获取root属性值

时间:2016-12-16 09:44:05

标签: java xml parsing xpath

我在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)不起作用。 有什么想法吗?

1 个答案:

答案 0 :(得分:1)

如果我理解正确,您正在尝试获取具有至少一个具有特定名称(id)的子元素的所有文档节点的特定属性(taxeelement

虽然问题可以通过迭代DOM并保持状态来解决,但我宁愿将此任务委托给XPath。使用XPath的代码看起来更干净,更易于维护。例如,为了获取具有属性idtaxe以及子元素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表达式获取名称等于idtaxe的所有属性节点。如果您想要所有属性,只需删除最后一个条件:

String expression = "//*[ " + element + "]/@*";