搜索XML文件中特定属性名称的Java代码

huangapple go评论74阅读模式
英文:

java search specific attribut name in the xml file

问题

我想在我的 XML 文件中搜索所有没有使用元素标签节点的属性(name):

XML:

    <test1/>
    <test2> <test2/>
    <test3 id="aaa"> </test3>
    <test5> </test5>
    <test6 id="bbb" name="ijof"> </test6>

JAVA:

    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = factory.newDocumentBuilder();
    Document document = builder.parse(new File(path));
    root = document.getDocumentElement();

    String attribut = root.getAttribute("name");
    System.out.println(attribut); // 预期输出 ijof
英文:

I wouldlike to search in my xml file all attribut (name) without use element tag node :

xml :

<test 1><test1/>
<test2> <test2/>
<test 3 id="aaa"> </test3>
<test 5> </test5>
<test 6 id="bbb" name="ijof"> </test6>

JAVA :

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new File(path));
root = document.getDocumentElement();

String attribut = root.getAttribute("name");
System.out.println(attribut); // Expected ijof

答案1

得分: 1

你是否至少执行了一次你的代码?我认为没有。否则你肯定会注意到你的XML无法解析。

你的示例XML中存在几个问题:

  1. 没有根元素。
  2. 错误的闭合标签:应该是 <test1></test1> 而不是 <test1><test1/>
  3. 元素名称不能包含空格,开始和结束标签必须匹配。应为 <test5> </test5> 而不是 <test 5> </test5>

除此之外,你可以使用XPath获取所有带有 name 属性的元素。

这里是一个完整的示例,其中XML以字符串形式给出,但这应该是无关紧要的:

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import java.io.IOException;
import java.io.StringReader;

public class FindNameAttribute {

  private static final String XML =
    "<root>\n" +
    "  <test1></test1>\n" +
    "  <test2> </test2>\n" +
    "  <test3 id=\"aaa\"> </test3>\n" +
    "  <test4 name=\"4\"/>\n" +
    "  <test5> </test5>\n" +
    "  <test6 id=\"bbb\" name=\"ijof\"> </test6>\n" +
    "  <test7 id=\"bbb\"><child name=\"childname\"/> </test7>\n" +
    "</root>\n";

  public static void main(String[] args) {
    System.out.println(XML);

    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = null;
    try {
      builder = factory.newDocumentBuilder();
      StringReader reader = new StringReader(XML);
      InputSource source = new InputSource(reader);
      Document document = builder.parse(source);
      XPath xpath = XPathFactory.newInstance().newXPath();
      NodeList nodes = (NodeList) xpath.evaluate("//*[@name]", document, XPathConstants.NODESET);
      for(int i = 0; i < nodes.getLength(); i++) {
        Element el = (Element) nodes.item(i);
        String elementName = el.getTagName();
        String nameAttribute = el.getAttribute("name");
        System.out.println(String.format("Element name: %s, name attribute: %s", elementName, nameAttribute));
      }
    } catch (ParserConfigurationException | SAXException | IOException | XPathExpressionException e) {
      e.printStackTrace();
    }
  }
}

这是输出结果:

<root>
  <test1></test1>
  <test2> </test2>
  <test3 id="aaa"> </test3>
  <test4 name="4"/>
  <test5> </test5>
  <test6 id="bbb" name="ijof"> </test6>
  <test7 id="bbb"><child name="childname"/> </test7>
</root>

Element name: test4, name attribute: 4
Element name: test6, name attribute: ijof
Element name: child, name attribute: childname

相关的XPath表达式是://*[@name]

  • //:在文档中查找每个元素
  • *:元素名称的占位符。每个名称都匹配。
  • *[@name][] 表示谓词。我们只想要带有 name 属性的元素。
  • @:表示接下来的名称是属性的名称。如果没有它,将被解释为元素名称。
英文:

Did you execute your code at least once? I dont't think so. Otherwise you would have surely noticed that your XML cannot be parsed.

There are several flaws in your example XML:

  1. No root element.
  2. Wrong end tags: It should be &lt;test1&gt;&lt;/test1&gt; and not &lt;test1&gt;&lt;test1/&gt;.
  3. Element names must not contain whitespace and start and end tag must match. It should be &lt;test5&gt; &lt;/test5&gt; and not &lt;test 5&gt; &lt;/test5&gt;

Apart of that you can use XPATH to get all elements with a name attribute.

Here is a complete example with the XML as a string but this should be irrelevant:

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import java.io.IOException;
import java.io.StringReader;
public class FindNameAttribute {
private static final String XML =
&quot;&lt;root&gt;\n&quot; +
&quot;  &lt;test1&gt;&lt;/test1&gt;\n&quot; +
&quot;  &lt;test2&gt; &lt;/test2&gt;\n&quot; +
&quot;  &lt;test3 id=\&quot;aaa\&quot;&gt; &lt;/test3&gt;\n&quot; +
&quot;  &lt;test4 name=\&quot;4\&quot;/&gt;\n&quot; +
&quot;  &lt;test5&gt; &lt;/test5&gt;\n&quot; +
&quot;  &lt;test6 id=\&quot;bbb\&quot; name=\&quot;ijof\&quot;&gt; &lt;/test6&gt;\n&quot; +
&quot;  &lt;test7 id=\&quot;bbb\&quot;&gt;&lt;child name=\&quot;childname\&quot;/&gt; &lt;/test7&gt;\n&quot; +
&quot;&lt;/root&gt;\n&quot;;
public static void main(String[] args) {
System.out.println(XML);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = null;
try {
builder = factory.newDocumentBuilder();
StringReader reader = new StringReader(XML);
InputSource source = new InputSource(reader);
Document document = builder.parse(source);
XPath xpath = XPathFactory.newInstance().newXPath();
NodeList nodes = (NodeList) xpath.evaluate(&quot;//*[@name]&quot;, document, XPathConstants.NODESET);
for(int i = 0; i &lt; nodes.getLength(); i++) {
Element el = (Element) nodes.item(i);
String elementName = el.getTagName();
String nameAttribute = el.getAttribute(&quot;name&quot;);
System.out.println(String.format(&quot;Element name: %s, name attribute: %s&quot;, elementName, nameAttribute));
}
} catch (ParserConfigurationException | SAXException | IOException | XPathExpressionException e) {
e.printStackTrace();
}
}
}

This is the output:

&lt;root&gt;
&lt;test1&gt;&lt;/test1&gt;
&lt;test2&gt; &lt;/test2&gt;
&lt;test3 id=&quot;aaa&quot;&gt; &lt;/test3&gt;
&lt;test4 name=&quot;4&quot;/&gt;
&lt;test5&gt; &lt;/test5&gt;
&lt;test6 id=&quot;bbb&quot; name=&quot;ijof&quot;&gt; &lt;/test6&gt;
&lt;test7 id=&quot;bbb&quot;&gt;&lt;child name=&quot;childname&quot;/&gt; &lt;/test7&gt;
&lt;/root&gt;
Element name: test4, name attribute: 4
Element name: test6, name attribute: ijof
Element name: child, name attribute: childname

The relevant XPATH expression is: //*[@name]

  • //: Looks for every element in the document
  • *: Placeholder for element name. Each name matches.
  • *[@name]: The [] denotes the predicate. We only want elements with a name attribute.
  • @: Means the following name is the name of an attribute. Whithout it would be interpreted as an element name

huangapple
  • 本文由 发表于 2020年9月7日 20:34:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/63777754.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定