如何通过元素ID读取XML?
这是我现在的XML文件,它给了我不同字符的对话,或者至少它应该。我希望它能够工作,以便我可以指定实体标识和选项/任务标识并获取输出。所以我该怎么做?任何帮助表示赞赏,非常感谢。如何通过元素ID读取XML?
<?xml version="1.0"?>
<dialoge>
<entity id="1"> <!-- questgiver -->
<quest id="1">
<option id="1">
<precondition>player has not started quest</precondition>
<output>hello there, can you kill 2 enemies for me?</output>
</option>
<option id="2">
<precondition>player has completed quest and player has not...</precondition>
<output>thankyou, have a sword for your troubles.</output>
</option>
<option id="3">
<precondition>player has not finished quest</precondition>
<output>you haven't finished yet.</output>
</option>
<option id="4">
<outpur>thank you.</outpur>
</option>
</quest>
</entity>
<entity id="2"> <!-- villager -->
<option id="1">
<precondition>village is being destroyed</precondition>
<output>our village is being destroyed, please help us!</output>
</option>
<option id="2">
<precondition>village has been saved or destroyed</precondition>
<output>we will never forget this.</output>
</option>
<option id="3">
<output>hello.</output>
</option>
</entity>
</dialoge>
这是我目前有,但它不起作用。我知道这可能是一个愚蠢的问题,但我无法在网络上的任何地方找到答案。谢谢。
public static void read() {
try {
File file = new File("text.xml");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(file);
doc.getDocumentElement().normalize();
System.out.println("root of xml file " + doc.getDocumentElement().getNodeName());
NodeList nodes = doc.getElementsByTagName("entity");
System.out.println("==========================");
for(int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
if(node.getNodeType() == Node.ELEMENT_NODE) {
Element element = (Element) node;
if(element.getElementsByTagName("entity").item(0).getTextContent().equals("output")) {
}
System.out.println("" + getValue("output", element));
}
}
}catch(Exception e) {
e.printStackTrace();
}
}
private static String getValue(String tag, Element element) {
NodeList nodes = element.getElementsByTagName(tag).item(0).getChildNodes();
Node node = (Node) nodes.item(0);
return node.getNodeValue();
}
最简单的方法可能是使用XPath ......
try {
File file = new File("text.xml");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(file);
doc.getDocumentElement().normalize();
XPath xpath = XPathFactory.newInstance().newXPath();
XPathExpression xExpress = xpath.compile("//*[@id='1']");
NodeList nl = (NodeList) xExpress.evaluate(doc, XPathConstants.NODESET);
System.out.println("Found " + nl.getLength() + " matches");
} catch (Exception e) {
e.printStackTrace();
}
XPath查询//*[@id='1']
会发现其中有属性id
与1
有价文件中的所有节点看看WC3 XPath Tutorial和How XPath works关于XPath的更多细节
一般来说, DOM更容易使用,但在开始使用之前会分析entire XML
,因为SAX parser
正在解析XML,并且遇到标签开始(例如, <something>
),则触发startElement
事件(事件的实际名称可能不同)。 read more..
见Java教程上Parsing an XML File Using SAX
下面是示例代码:
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class GetElementAttributesInSAXXMLParsing extends DefaultHandler {
public static void main(String[] args) throws Exception {
DefaultHandler handler = new GetElementAttributesInSAXXMLParsing();
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setValidating(false);
SAXParser parser = factory.newSAXParser();
parser.parse(new File("text.xml"), handler);
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes)
throws SAXException {
System.out.println("Tag Name:"+qName);
// get the number of attributes in the list
int length = attributes.getLength();
// process each attribute
for (int i = 0; i < length; i++) {
// get qualified (prefixed) name by index
String name = attributes.getQName(i);
System.out.println("Attribute Name:" + name);
// get attribute's value by index.
String value = attributes.getValue(i);
System.out.println("Attribute Value:" + value);
}
}
}
感谢您发布此信息,它非常有帮助,但我对startElement()感到困惑,在我看来它会自动调用,这是怎么发生的?还有什么是引用String uri,String localName等等的变量。谢谢你的帮助。 –
@ user3053027它被称为访客模式。 sax解析器会在读取XML文档时自动调用处理程序的方法以响应更改。如果您只想从头到尾解析文档一次,此方法非常有用。如果要分别查询文档,则需要使用DOM方法,这将允许您随时跳到文档中,随意移动并执行重复查询...... – MadProgrammer
如果我想找到只为'entity'标签? :) – Braj
'// entity [@ id ='1']'或'// entity'如果你想要所有的实体,不管id值 – MadProgrammer
看到我的xml文件有两个不同的元素与id的,他们都有孩子也有id的元素,我该如何去寻找它们?我会做实体[@ id ='1'],然后选择[@ id ='1']吗?谢谢,这似乎是一个很好的解决方案。 –