【问题标题】:Retrieving attributes and values of child Nodes of an XML Element in Java在 Java 中检索 XML 元素的子节点的属性和值
【发布时间】:2023-04-11 04:16:01
【问题描述】:

请问,在下面的 XML 结构中,如何获取带有属性“AdvancedAlgorithm”的 XML 课程标签名称中第二个的属性值:

<course name="AdvancedAlgorithm">
    <Teacher name="Francis" class="A" />
    <Teacher name="John" class="B" />
    <Teacher name="Philips" class="C" />
    <course name="AlgorithmForBeginners">
        <Teacher name="Simon" class="E" />
        <Teacher name="Joan" class="F" />
    </course>
    <Teacher name="Edward" class="M" />
</course>

我尝试了各种方法来获取它,但不知何故它首先给了我一个错误的长度和一个错误的值。我在下面的代码中做错了什么?

 public void getStructure(NodeList list){

    for(int i= 0;i<list.getLength();i++){
        Element element = (Element)list.item(i);
           if(element.getNodeType()==Node.ELEMENT_NODE && element.getAttribute("name").equals("AdvancedAlgorithm"))
         {
                NodeList node = element.getChildNodes(); //get the child elements
                System.out.println(node.getLength());
                for(int k=0; k<node.getLength();k++){
                    Node currentNode = node.item(i);
                    Element e = (Element)currentNode;
                    System.out.println(e.getAttribute("name"));

            }

         }
    }

我的分析: NodeList 列表的长度为 2。鉴于 XML 有两个 course 标签,但当我将 Element 元素的 ChildNodes 分配给 NodeList 节点并检查 NodeList 节点的长度时,这是真的吗,我发现它是 11而不是 5,因为该节点有 5 个子节点。我关心的是,首先,我想知道这个 XML 结构的长度是多少,其次,如何检索第二个 .谢谢

【问题讨论】:

    标签: java xml dom


    【解决方案1】:

    我不确定你到底想做什么,但 XPath 可能会解决这个问题。这是一个使用您提供的 XML sn-p 的快速示例:

    public static void main(String[] args) throws UnsupportedEncodingException, ParserConfigurationException, SAXException, IOException, XPathExpressionException {
        final String xml = "<course name=\"AdvancedAlgorithm\">\n"
                + "    <Teacher name=\"Francis\" class=\"A\" />\n"
                + "    <Teacher name=\"John\" class=\"B\" />\n"
                + "    <Teacher name=\"Philips\" class=\"C\" />\n"
                + "    <course name=\"AlgorithmForBeginners\">\n"
                + "        <Teacher name=\"Simon\" class=\"E\" />\n"
                + "        <Teacher name=\"Joan\" class=\"F\" />\n"
                + "    </course>\n"
                + "    <Teacher name=\"Edward\" class=\"M\" />\n"
                + "</course>";
        final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new ByteArrayInputStream(xml.getBytes("UTF-8")));
        final XPath xPath = XPathFactory.newInstance().newXPath();
        final XPathExpression expression = xPath.compile("//course[@name='AdvancedAlgorithm']//Teacher");
    
        final NodeList nodeList = (NodeList) expression.evaluate(doc, XPathConstants.NODESET);
    
        for (int i = 0; i < nodeList.getLength(); ++i) {
            System.out.println(((Element)nodeList.item(i)).getAttribute("name"));
        }
    }
    

    输出:

    Francis
    John
    Philips
    Simon
    Joan
    Edward
    

    所以 Document 是构建的(在这种情况下是从 String 构建的),然后我们创建并编译一个 XPathExpression。这个表达式,//course[@name='AdvancedAlgorithm']//Teacher,意味着找到文档中的所有“Teacher”元素,无论它们在哪里,只要它们在某处有一个名为“AdvancedAlgorithm”的课程作为父级。

    表达式//course[@name='AdvancedAlgorithm']/course 将产生一个值“AlgorithmForBeginners”,因为它要求所有课程名称为“AdvancedAlgorithm”的课程作为直接父级。

    表达式//course[@name='AdvancedAlgorithm']/course[@name='AlgorithmForBeginners']/Teacher 将查找所有名为“AlgorithmForBeginners”的课程,其直接父级是名为“AdvancedAlgorithm”的课程,并列出所有作为直接子级的Teacher 元素。

    要查找名为“AlgorithmForBeginners”的任何课程的所有教师,您可以将//course[@name='AlgorithmForBeginners']/Teacher 用于直系儿童或使用//course[@name='AlgorithmForBeginners']//Teacher 用于任何儿童,即直接或间接。

    这就是你要找的东西吗?我不确定“秒的属性值”是什么意思。

    【讨论】:

    • 嗨@bmorris,虽然这很好。如果你有一个很大的 XML 会不会很麻烦?有没有其他方法可以在不使用 XPath 的情况下做到这一点?如果我想使用 XPath 仅查找“AlgorithmForBeginners”类中的教师,该怎么办?虽然,我不想使用 XPath,但学习它仍然会很好,以防万一:)
    • 已编辑以显示这些查询。 XPath 的全部意义在于处理大型 xml 文件!它旨在智能地查询数据,而不仅仅是循环并尝试找到您想要的东西 - 而不是您的两个嵌套循环 XPath 有一个单一的表达式,两者都描述了您要查找的内容阅读代码并找到它。繁琐是什么意思?
    • 谢谢。我会试试这个,看看效果如何。也许现在对我来说是唯一的选择,因为我尝试使用 DOM 是徒劳的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-30
    • 2011-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-07
    • 1970-01-01
    相关资源
    最近更新 更多