我正在尝试编辑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><add connectionString="Data Source=XXXX;user Id=NEWVALUE;password=ZZZZZ;" name="Entities" providerName="Oracle.ManagedDataAccess.Client"/></connectionStrings>
</connectionStrings>
</configuration>
我尝试过更改编码类型但没有成功。
答案 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"
。 nodeName
方法用于设置文本内容,即&gt;&lt;之间的文本。一些元素。区分元素,属性和文本内容是必要的,并且要意识到这些不可互换的事实。通过添加看起来像(格式化为)元素的文本内容,无法添加新元素。请注意,新代码尚未生产就绪,因为至少需要添加对潜在setTextContent
值的处理,例如:关于null
的结果。