当我们复杂的hericarchy时,如何解析XML并更新它?

时间:2014-10-15 04:42:40

标签: java xml-parsing

假设我有以下XML文件内容

<CREDENTIALS>
   <SCENERIOONE> 
      <USERNAME>stackoverflow</USERNAME>
      <PASSWORD>argmishra</PASSWORD>
   </SCENERIOONE>
   <SCENERIOTWO> 
      <USERNAME>stackexchnage</USERNAME>
      <PASSWORD>mishraarg</PASSWORD>
   </SCENERIOTWO>
</CREDENTIALS>

我想检索SCENERIOONE的数据(用户名和密码)并检查并在需要时更新它,对于SCENERIOTWO也是如此。

如果我用SCENERIOONE替换了SCENERIOTWO,那么我能够检索数据,即CREDENTIALS的子节点是相同的。

但是如果一个父节点的子节点不同,则无法检索。

编辑:

现在,我可以通过传递场景来检索XML中的数据: -

try {
  File file = new File("D://DemoWorkSpace//XMLDemo//lib//MyXMLFile.xml");
  DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
  DocumentBuilder db = dbf.newDocumentBuilder();
  Document doc = db.parse(file);
  doc.getDocumentElement().normalize();
  System.out.println("Root element " + doc.getDocumentElement().getNodeName());
  NodeList nodeLst = doc.getElementsByTagName("MEMBER_BENEFITS");
  System.out.println("Information of all employees");

  for (int s = 0; s < nodeLst.getLength(); s++) {

    Node fstNode = nodeLst.item(s);

    if (fstNode.getNodeType() == Node.ELEMENT_NODE) {
      Element fstElmnt = (Element) fstNode;
      NodeList fstNmElmntLst = fstElmnt.getElementsByTagName("USERNAME");
      Element fstNmElmnt = (Element) fstNmElmntLst.item(0);
      NodeList fstNm = fstNmElmnt.getChildNodes();
      System.out.println("User Name : "  + ((Node) fstNm.item(0)).getNodeValue());
      NodeList lstNmElmntLst = fstElmnt.getElementsByTagName("PASSWORD");
      Element lstNmElmnt = (Element) lstNmElmntLst.item(0);
      NodeList lstNm = lstNmElmnt.getChildNodes();
      System.out.println("Password : " + ((Node) lstNm.item(0)).getNodeValue());
    }

  }
  } catch (Exception e) {
    e.printStackTrace();
  }

但我不知道如何更新XML文件?

2 个答案:

答案 0 :(得分:2)

如果我理解正确,你真正关注的是用户名/密码节点,无论它们在文档中的位置......

您可以使用XPath查询文档以返回您想要的内容,例如......

try (InputStream is = TestXML.class.getResourceAsStream("/Credentials.xml")){

    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    DocumentBuilder db = dbf.newDocumentBuilder();
    Document dom = db.parse(is);
    XPath xpath = XPathFactory.newInstance().newXPath();

    XPathExpression xExpress = xpath.compile("//*[USERNAME and PASSWORD]/*");
    NodeList nodeList = (NodeList) xExpress.evaluate(dom, XPathConstants.NODESET);
    for (int index = 0; index < nodeList.getLength(); index++) {

        Node node = nodeList.item(index);
        System.out.println(node.getNodeName());

    }

} catch (Exception exp) {
    exp.printStackTrace();
}

将输出......

USERNAME
PASSWORD
USERNAME
PASSWORD

如果它很重要,您可以使用Node s parent属性查找父节点,显然,getTextContent可以获取节点文本内容

您可以根据需要正常操作节点

<强>更新

因此,根据评论,您应该能够做类似......

的事情
try {

    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    DocumentBuilder db = dbf.newDocumentBuilder();
    Document dom = db.parse(new File("Credentials.xml"));
    XPath xpath = XPathFactory.newInstance().newXPath();

    String scenerio = "SCENERIOONE";

    XPathExpression xExpress = xpath.compile("/CREDENTIALS/" + scenerio + "/[USERNAME and PASSWORD]/*");
    NodeList nodeList = (NodeList) xExpress.evaluate(dom, XPathConstants.NODESET);
    for (int index = 0; index < nodeList.getLength(); index++) {

        Node node = nodeList.item(index);
        System.out.println(node.getNodeName());

    }

} catch (Exception exp) {
    exp.printStackTrace();
}

这将返回USERNAME

PASSWORDSCENERIOONE个节点

您可以使用node.get/setTextContent按正常方式获取/设置文字。

当你需要时,你可以使用像...这样的东西。

Transformer tf = TransformerFactory.newInstance().newTransformer();
tf.setOutputProperty(OutputKeys.INDENT, "yes");
tf.setOutputProperty(OutputKeys.METHOD, "xml");
tf.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
StreamResult result = new StreamResult(new File("Credentials.xml"));
tf.transform(dom, result);

保存它......

答案 1 :(得分:0)

$server_output = "<CREDENTIALS>
<SCENERIOONE> 
  <USERNAME>stackoverflow</USERNAME>
  <PASSWORD>argmishra</PASSWORD>
</SCENERIOONE>
<SCENERIOTWO> 
  <USERNAME>stackexchnage</USERNAME>
  <PASSWORD>mishraarg</PASSWORD>
</SCENERIOTWO>
</CREDENTIALS>";

$xml = simplexml_load_string($server_output);
$json = json_encode($xml);
$array = json_decode($json,TRUE);


foreach ($array as $key => $value) {
   $username = $value['USERNAME'];
   $password = $value['PASSWORD'];
}

Here is the output:
stackoverflow
argmishra
stackexchnage
mishraarg