如何使用Java获取XML节点的属性值

21

我有一个长这样的xml:

{ <xml><ep><source type="xml">...</source><source type="text">..</source></ep></xml>}

我想获取"source type"的值,其中type是一个属性。

我尝试了以下方法,但没有成功:

DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
try {
    DocumentBuilder builder = domFactory.newDocumentBuilder();
    Document dDoc = builder.parse("D:/workspace1/ereader/src/main/webapp/configurations/config.xml");
    System.out.println(dDoc);
    XPath xPath = XPathFactory.newInstance().newXPath();
    Node node = (Node) xPath.evaluate("//xml/source/@type/text()", dDoc, XPathConstants.NODE);
    System.out.println(node);
} catch (Exception e) {
    e.printStackTrace();

这个方法也不起作用:

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
InputSource is = new InputSource(new StringReader("config.xml"));
Document doc = builder.parse(is);

NodeList nodeList = doc.getElementsByTagName("source");

for (int i = 0; i < nodeList.getLength(); i++) {
    Node node = nodeList.item(i);

    if (node.hasAttributes()) {
        Attr attr = (Attr) node.getAttributes().getNamedItem("type");
        if (attr != null) {
            String attribute = attr.getValue();
            System.out.println("attribute: " + attribute);
        }
    }
}

你尝试过使用VTD-XML吗?http://vtd-xml.sourceforge.net/ 它更快,更节省内存。 - Rosdi Kasim
嗨Rosdi,我还没有尝试过,不管怎样ATR的代码很好用,我的片段也是:)感谢您的友善回复。 - Priya
7个回答

34

由于您的问题比较通用,因此请尝试使用Java中可用的XML解析器进行实现。如果您需要特定的解析器,请在此处更新您已尝试的代码。

<?xml version="1.0" encoding="UTF-8"?>
<ep>
    <source type="xml">TEST</source>
    <source type="text"></source>
</ep>
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse("uri to xmlfile");
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
XPathExpression expr = xpath.compile("//ep/source[@type]");
NodeList nl = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);

for (int i = 0; i < nl.getLength(); i++)
{
    Node currentItem = nl.item(i);
    String key = currentItem.getAttributes().getNamedItem("type").getNodeValue();
    System.out.println(key);
}

1
我已尝试上述代码片段,但不知道如何继续,请帮助我!我只需要获取"value"和"text"这两个值。这是我的要求。 - Priya
1
ATR,实际上是//xml/ep/source/@type。我在你的代码中编辑了几个语句...现在它可以正常工作了..谢谢 :) - Priya
有没有办法获取标签之间的值,在上面的示例中,<source type="xml">TEST</source>,我该如何读取 TEST? - Srikanth Josyula

4

试试这样的做法:

    DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
    Document dDoc = builder.parse("d://utf8test.xml");

    XPath xPath = XPathFactory.newInstance().newXPath();
    NodeList nodes = (NodeList) xPath.evaluate("//xml/ep/source/@type", dDoc, XPathConstants.NODESET);
    for (int i = 0; i < nodes.getLength(); i++) {
        Node node = nodes.item(i);
        System.out.println(node.getTextContent());
    }

请注意以下更改:
  • 我们要求一个节点集(XPathConstants.NODESET),而不仅仅是单个节点。
  • XPath现在为//xml/ep/source/@type,而不是//xml/source/@type/text()

注:您能否将java标签添加到您的问题中?谢谢。


mabroukb,谢谢:) 添加了Java标签:) 你的解释让我清楚了.. 非常感谢!! - Priya

2

我很高兴这段代码能够正常工作:

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document document = db.parse(new File("config.xml"));
NodeList nodeList = document.getElementsByTagName("source");
for(int x=0,size= nodeList.getLength(); x<size; x++) {
    System.out.println(nodeList.item(x).getAttributes().getNamedItem("type").getNodeValue());
} 

1

使用

document.getElementsByTagName(" * ");

可以获取XML文件中的所有XML元素,但是会返回重复的属性。

例如:

NodeList list = doc.getElementsByTagName("*");


System.out.println("XML Elements: ");

        for (int i=0; i<list.getLength(); i++) {

            Element element = (Element)list.item(i);
            System.out.println(element.getNodeName());
        }

1
以下是使用VTD-XML完成此操作的代码。
import com.ximpleware.*;

public class queryAttr{
     public static void main(String[] s) throws VTDException{
         VTDGen vg= new VTDGen();
         if (!vg.parseFile("input.xml", false))
            return false;
         VTDNav vn = vg.getNav();
         AutoPilot ap = new AutoPilot(vn);
         ap.selectXPath("//xml/ep/source/@type");
         int i=0;
         while((i = ap.evalXPath())!=-1){
               system.out.println(" attr val ===>"+ vn.toString(i+1));

         }
     }
}

0
public static void main(String[] args) throws IOException {
    String filePath = "/Users/myXml/VH181.xml";
    File xmlFile = new File(filePath);
    DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder dBuilder;
    try {
        dBuilder = dbFactory.newDocumentBuilder();
        Document doc = dBuilder.parse(xmlFile);
        doc.getDocumentElement().normalize();
        printElement(doc);
        System.out.println("XML file updated successfully");
    } catch (SAXException | ParserConfigurationException e1) {
        e1.printStackTrace();
    }
}
private static void printElement(Document someNode) {
    NodeList nodeList = someNode.getElementsByTagName("choiceInteraction");
    for(int z=0,size= nodeList.getLength();z<size; z++) {
            String Value = nodeList.item(z).getAttributes().getNamedItem("id").getNodeValue();
            System.out.println("Choice Interaction Id:"+Value);
        }
    }

我们可以尝试使用这段代码的方法


0
以下是我编写的实用方法,用于从根文档对象和给定的XPATH获取任何节点的值。
public String getValue(Document doc, String xPath) throws Exception {
   XPathFactory factory = XPathFactory.newInstance();
   XPath path = factory.newXPath();
   XPathExpression expression = path.compile(xPath);
   Node node = (Node) expression.evaluate(doc,XPathConstants.NODE);
   return node.getFirstChild().getNodeValue();
}

所有的库都来自于 java.xml.xpathorg.w3c.dom。

现在你只需要根文档元素和正确的路径。 对于你的例子,路径将是 /ep/source/@type

因此,基本上XPath是用来导航到你想要的元素,然后跟着你感兴趣的/@attributeName

请注意,/ep/source@type 不起作用。(我浪费了30分钟来解决这个问题)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接