使用Java保存XML文件时出现特殊字符错误(“<”和“>”)

时间:2016-06-13 16:54:22

标签: java xml

我正在尝试编辑XML文件中的特定键。问题是文件保存后,'<'和'>'字符用编码字符转换(分别为:“& lt;”和“& gt;”)。

XML文件:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>

  </configSections>

  <system.web>    
    <httpRuntime targetFramework="X.X"/>
  </system.web>

  <connectionStrings>
    <add connectionString="Data Source=XXXX;user Id=YYYYY;password=ZZZZZ;" name="Entities" providerName="Oracle.ManagedDataAccess.Client"/>
  </connectionStrings>

</configuration>

我正在更新整个connectionStrings键的值:

package br.com.sedna.bitbucket.plugin.enviromentsetup.utils;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

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

public class ModifyXmlFile {
    private File _inputFile; 
    private String _filePath;
    private DocumentBuilderFactory _docFactory;
    private DocumentBuilder _docBuilder;
    private Document _doc;
    private Node _xmlObject;
    private String CONNECTION_STRINGS = "<add connectionString=\"Data Source=XXXX;user     Id=%s;password=ZZZZZ;\" name=\"Entities\"     providerName=\"Oracle.ManagedDataAccess.Client\"/>";

    public ModifyXmlFile(String xmlPath){

        try {
            this._filePath = xmlPath;
            this._inputFile = new File(this._filePath);             
            this._docFactory = DocumentBuilderFactory.newInstance();
            this._docBuilder = _docFactory.newDocumentBuilder();
            this._doc = _docBuilder.parse(_inputFile);
            this._xmlObject = _doc.getFirstChild();

        } catch (ParserConfigurationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SAXException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public ModifyXmlFile setNodeValue(String nodeName, String nodeValue){

        Node nodeNameObject = this._doc.getElementsByTagName(nodeName).item(0);


        try {

            // updating the value of connectionStrings key
            nodeNameObject.setTextContent(String.format(CONNECTION_STRINGS, nodeValue));                

            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer;

            transformer = transformerFactory.newTransformer();
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            transformer.setOutputProperty(OutputKeys.ENCODING, "utf-8");

            DOMSource source = new DOMSource(this._doc);
            StreamResult consoleResult = new StreamResult(new File(this._filePath));
            transformer.transform(source, consoleResult);

            System.out.println("Done");
        } catch (TransformerConfigurationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (TransformerException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


        return this;
    }
}

运行此课程:

ModifyXmlFile xmlHelper = new ModifyXmlFile("C:\\Web.config");
xmlHelper.setNodeValue("connectionStrings", "NEWVALUE");

结果:

  <?xml version="1.0" encoding="utf-8"?>
  <configuration>
    <configSections>

    </configSections>

    <system.web>    
      <httpRuntime targetFramework="X.X"/>
    </system.web>

    <connectionStrings>&lt;add connectionString="Data Source=XXXX;user Id=NEWVALUE;password=ZZZZZ;" name="Entities" providerName="Oracle.ManagedDataAccess.Client"/&gt;</connectionStrings>
    </connectionStrings>

  </configuration>

我尝试过更改编码类型但没有成功。

1 个答案:

答案 0 :(得分:1)

我修改了setNodeValue方法。相关部分如下:

    public ModifyXmlFile setElementAttributeValue(String nodeXPath, String attributeName, String newAttributeValue) throws XPathExpressionException{

    try {
        XPath xPath = XPathFactory.newInstance().newXPath();
        Node node = (Node)xPath.evaluate(nodeXPath,  _doc, XPathConstants.NODE);
        node.getAttributes().getNamedItem(attributeName).setNodeValue(String.format(CONNECTION_STRINGS, newAttributeValue));

通过

调用此方法
setElementAttributeValue("/configuration/connectionStrings/add",     "connectionString", "NEWVALUE" );

更改元素connectionString上的属性add的值。

原始代码中存在几个问题:

  • consoleResult名称令人困惑 - StreamResult指向文件
  • 参数nodeName实际上代表要编辑的元素的父节点,这确实是每个this._doc.getElementsByTagName(nodeName).item(0)检索的内容 - 至少在使用{{1}调用setNodeValue时} "connectionStrings"
  • 要编辑的属性的名称已硬连接到代码中。
  • 作为T.J. Crowder提到,原始代码调用的nodeName方法用于设置文本内容,即&gt;&lt;之间的文本。一些元素。区分元素,属性和文本内容是必要的,并且要意识到这些不可互换的事实。通过添加看起来像(格式化为)元素的文本内容,无法添加新元素。

请注意,新代码尚未生产就绪,因为至少需要添加对潜在setTextContent值的处理,例如:关于null的结果。