Java中的W3C DOM API,按名称获取子元素

Posted

技术标签:

【中文标题】Java中的W3C DOM API,按名称获取子元素【英文标题】:W3C DOM API in Java, get child elements by name 【发布时间】:2011-02-08 01:46:26 【问题描述】:

我刚刚意识到Element.getElementsByTagName("someTagName") 方法返回文档中具有给定标记名的所有元素的节点列表。如果我只想通过标签名获取所有子元素怎么办?

例如……

<person>
  <name>Bob</name>
  <car>
    <name>Toyota Corolla</name>
  </car>
</person>

【问题讨论】:

【参考方案1】:

并非文档中的所有元素——调用它的元素的所有后代元素。听起来这就是你想要的。您只需要在右侧调用它Element。见here。

【讨论】:

【参考方案2】:

getElementsByTagName 总是在它被调用的元素的上下文中运行。如果在Element 上调用,则只会访问给定标签名称的子元素。 我认为您将此与Document 对象(org.w3c.dom.Document)getElementsByTagName 方法混淆了,然后将返回文档中给定标签名称的所有元素。

【讨论】:

它是 getElementsByTagName。 恐怕不对——这个方法返回后代元素,所以例如在代表person元素的Element上执行的getElementsByTagName("name")会返回2个节点。 @ArturNowak 我不关注。它返回哪两个?包含“Bob”和“Toyota Corolla”的node @Pureferret 没错——两个节点:一个包含内容“Bob”,另一个包含“Toyota Corolla” 最糟糕的是我们不能依赖节点顺序。第一个节点并不总是“第一个直接子节点”。如果我们在元素“/person/car”之后有元素“/person/name”,那么“Toyota Corolla”将是索引(0)处的节点【参考方案3】:

我遇到了类似的问题。尝试查看 Node 类:

http://java.sun.com/javase/6/docs/api/org/w3c/dom/Node.html#getChildNodes()

有一个名为“getChildNodes”的方法,它返回所有个直接子节点的列表。然后,您需要过滤该列表以仅获取具有正确标记名的元素节点。

【讨论】:

【参考方案4】:
public static Element getDirectChild(Element parent, String name)

    for(Node child = parent.getFirstChild(); child != null; child = child.getNextSibling())
    
        if(child instanceof Element && name.equals(child.getNodeName())) return (Element) child;
    
    return null;

【讨论】:

就我而言,我发现修改 if 条件以检查 localName 很有帮助: if (child instanceof Element && (name.equals(child.getLocalName()) || name.equals( child.getNodeName()))) 【参考方案5】:

遇到了同样的问题,但没有一个答案真正解决了这个问题。

我试图查询 WSDL 的 portType 节点内的操作节点,因为绑定节点也有操作。

<portType name="MyService">
    <operation name="op1">
      <input wsam:Action="http://somedomain.org/MyService/MyServiceRequest" message="tns:MyServiceRequest"/>
      <output wsam:Action="http://somedomain.org/MyService/MyServiceResponse" message="tns:MyServiceResponse"/>
    </operation>
    ...
</portType>
<binding name="MyServicePortBinding" type="tns:MyService">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
    <operation name="op1">
      <soap:operation soapAction=""/>
      <input>
        <soap:body use="literal"/>
      </input>
      <output>
        <soap:body use="literal"/>
      </output>
    </operation>
</binding>

通过找到父级 (portTypes) 并将其从 Node 转换为 Element 并使用上面提到的方法来解决它。

Node portType = document.getElementsByTagName("portType").item(0);
NodeList operations = ((Element)portType).getElementsByTagName("operation");

结果只给了我操作元素 INSIDE portType Node。

【讨论】:

以上是关于Java中的W3C DOM API,按名称获取子元素的主要内容,如果未能解决你的问题,请参考以下文章

Java 中的 org.w3c.dom.Node 和 Node 有啥区别?

从 Java DOM 中的 XML 获取元素名称

org.w3c.dom(java dom)解析XML文档

java.lang.NoClassDefFoundError: org/w3c/dom/ElementTraversal 的解决办法

react中的核心概念

从 org.w3c.dom.Node 获取 Xpath