繁体   English   中英

当我们复杂的体系结构时,如何解析XML并更新它?

[英]How to parse a XML and update it when we are complicated hericarchy?

假设我有以下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文件?

如果我理解正确,那么您真正想要的是用户名/密码节点,无论它们在文档中的位置如何。

您可以使用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

如果重要的话,可以使用Nodeparent属性来找到父节点,显然可以使用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();
}

它将返回SCENERIOONEUSERNAMEPASSWORD节点

您可以按常规使用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);

要保存...

$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 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM