如何更改XML文件中的特定行?

时间:2015-06-24 22:32:17

标签: java text special-characters

我有一个非常长的配置文件(不是我自己的),我想更改其中的特定行。

我需要将ServerPort值更改为12345,但没有代码知道实际数字..(26900)。

这是配置文件的一小部分:

<?xml version="1.0"?>
<ServerSettings>
  <property name="ServerPort"               value="26900"/>             <!-- Port you want the server to listen on. -->
  <property name="ServerIsPublic"           value="true"/>              <!-- Should this server register to master server -->
  <property name="ServerName"               value="My Game Host"/>      <!-- Whatever you want the name to be. -->
  <property name="ServerPassword"           value=""/>                  <!-- Password to gain entry to the server -->
  <property name="ServerMaxPlayerCount"     value="8"/>                 <!-- Maximum Concurrent Players -->
  <property name="ServerDescription"        value="A 7 Days to Die server"/> <!-- Whatever you want the description to be. -->
  <property name="ServerWebsiteURL"         value=""/>                  <!-- Website URL for the server -->

4 个答案:

答案 0 :(得分:2)

您提到的文件是一个xml文件。只需使用xml解析器+构建器,您就可以更轻松地读取和更新字段。

答案 1 :(得分:2)

简单的答案是使用XML解析器并更改所需的属性值。要搜索节点 - 请使用XPath。

我们来看看你的XML文件:

<强> xmlfile.xml

<ServerSettings>
  <property name="ServerPort"               value="26900"/>             <!-- Port you want the server to listen on. -->
  <property name="ServerIsPublic"           value="true"/>              <!-- Should this server register to master server -->
  <property name="ServerName"               value="My Game Host"/>      <!-- Whatever you want the name to be. -->
  <property name="ServerPassword"           value=""/>                  <!-- Password to gain entry to the server -->
  <property name="ServerMaxPlayerCount"     value="8"/>                 <!-- Maximum Concurrent Players -->
  <property name="ServerDescription"        value="A 7 Days to Die server"/> <!-- Whatever you want the description to be. -->
  <property name="ServerWebsiteURL"         value=""/>                  <!-- Website URL for the server -->
</ServerSettings>

例如,使用DOM解析器并使用XPath获取节点

    File file = new File("xmlfile.xml");
    DocumentBuilder dBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
    Document xml = dBuilder.parse(file);
    XPath xpath = XPathFactory.newInstance().newXPath();
    Node portNode = (Node) xpath.compile("/ServerSettings/property[@name='ServerPort']").evaluate(xml, XPathConstants.NODE);
    portNode.getAttributes().getNamedItem("value").setNodeValue("8080");

    // Saving changed XML back
    Transformer transformer = TransformerFactory.newInstance().newTransformer();
    Result output = new StreamResult(new File("xmlfile.xml"));
    Source input = new DOMSource(xml);
    transformer.transform(input, output);

将从26900变为8080。
如果您的文件非常大(如几十兆字节),最好使用SAX解析器或尝试使用正则表达式搜索它。如果它的常规设置文件值几千字节 - 上面的代码是最简单的。

答案 2 :(得分:1)

在这种特定情况下,您需要XML解析器。 无法将XML解析与常规文件修改进行比较。

我正在使用jdom进行xml解析。你可以从网上下载这个jdom.jar

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;

public class Sample1 {
    public static void main(String[] args) throws IOException, JDOMException {

        File file = new File("c:\\file.xml");
        Document doc = new SAXBuilder().build(file);

        Element rootElement = doc.getRootElement();

        for (Object child : rootElement.getChildren("property")) {
            Element el = (Element) child;
            if (el.getAttributeValue("name").equalsIgnoreCase("ServerPort")) {
                el.setAttribute("value", "12345");
            }
        }

        XMLOutputter xmlOutput = new XMLOutputter();

        xmlOutput.setFormat(Format.getPrettyFormat());
        xmlOutput.output(doc, new FileWriter("c:\\file.xml"));
    }

}

答案 3 :(得分:1)

您可以使用正则表达式查找并替换端口号:

要搜索的模式:

(<property name="ServerPort"\s+?value=)"\d+?"

并替换为:

$1"12345"

12345是一个示例端口。

String fileContent = // open, read file.  Either line by line or the entirety
fileContent = fileContent.replaceAll("(<property name=\"ServerPort\"\\s+?value=)\"\\d+?\"", "$1\"12345\"");
// write fileContent back to disk.