java - 使用 TransformerFactory 更新 XML 文件会在节点之间添加空行
问题描述
我有以下方法来更新 XML 文件中的节点值
static public void updateRepositoryValue(String fileName, String xpath, String value){
try {
String rootPath = Paths.get(".").toAbsolutePath().normalize().toString();
String path = rootPath + "/src/main/resources/repository/" + fileName + ".xml";
DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
DocumentBuilder b = f.newDocumentBuilder();
Document doc = b.parse(new File(path));
XPath xPath = XPathFactory.newInstance().newXPath();
Node updatedNode = (Node) xPath.compile(xpath).evaluate(doc, XPathConstants.NODE);
updatedNode.setTextContent(value);
Transformer tf = TransformerFactory.newInstance().newTransformer();
tf.setOutputProperty(OutputKeys.INDENT, "yes");
tf.setOutputProperty(OutputKeys.METHOD, "xml");
tf.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
DOMSource domSource = new DOMSource(doc);
StreamResult sr = new StreamResult(new File(path));
tf.transform(domSource, sr);
}catch (Exception e){
e.printStackTrace();
}
}
从功能上讲,它有效。
问题是在每个节点更新后,此代码在每个文件内容行(节点)之间添加一个空行。
目前我使用上面的代码来更新secret
节点值,但我认为更新什么值并不重要。
所以从这
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<general>
<environment>staging</environment>
<tenantNameDev>automationdev</tenantNameDev>
<tenantName>automation5</tenantName>
<tenantNameProd>automation3</tenantNameProd>
<userName>automation5@yahoo.com</userName>
<userNameDev>automationdev@yahoo.com</userNameDev>
<incompleteDetailsNotification>Some of the details are incomplete or invalid</incompleteDetailsNotification>
<ui>
<multiValueAtt>Gender</multiValueAtt>
<incompleteDetailsNotification>Some of the details are incomplete or invalid</incompleteDetailsNotification>
</ui>
<api>
<ownerIdAnn>3052cb88-a5a6-40db-af95-e1225ecf45fe</ownerIdAnn>
<schemaIdAnn>f60566b1-be2b-40b1-9663-a7bb52ba2d3f</schemaIdAnn>
<ownerId>e3bd1480-09b5-4268-9126-6962238e9a1e</ownerId>
<schemaId>fd2941ad-276e-42b7-88fb-5054e8acdc8c</schemaId>
<ownerIdProd>5218f707-96de-4d4c-92c6-ebedd9ccbdbf</ownerIdProd>
<schemaIdProd>f50f2ac3-8e38-4733-adac-4817e3c58643</schemaIdProd>
<envClientId>PYJYF7XU017OGFH5RJ8Q</envClientId>
<secret>6MmE3bELLzO29r1ToG7LoVspWqanNJNGZCP0tG0N</secret>
<workspaceId>e3bd1480-09b5-4268-9126-6962238e9a1e</workspaceId>
<partnerId>b0f95322-a898-4af1-8fc1-9a8951d0c13a</partnerId>
<email>kukussfds@mailinator.com </email>
<alternativeWorkspaceId>81e15977-070a-4e68-8808-e2e6bb134f25</alternativeWorkspaceId>
<alternativeEnvClientId>PQSWUCNXVRL1LALUJBRJ</alternativeEnvClientId>
<alternativeSecret>VYpdpQ81n6p7i5C8FL2ni1RVOrHlD34ESxI1FW8U</alternativeSecret>
<serverDeployDelay>3500</serverDeployDelay>
</api>
</general>
4调用上面的方法后,我收到:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<general>
<environment>staging</environment>
<tenantNameDev>automationdev</tenantNameDev>
<tenantName>automation5</tenantName>
<tenantNameProd>automation3</tenantNameProd>
<userName>automation5@yahoo.com</userName>
<userNameDev>automationdev@yahoo.com</userNameDev>
<incompleteDetailsNotification>Some of the details are incomplete or
invalid</incompleteDetailsNotification>
<ui>
<multiValueAtt>Gender</multiValueAtt>
<incompleteDetailsNotification>Some of the details are incomplete or invalid</incompleteDetailsNotification>
</ui>
<api>
<ownerIdAnn>3052cb88-a5a6-40db-af95-e1225ecf45fe</ownerIdAnn>
<schemaIdAnn>f60566b1-be2b-40b1-9663-a7bb52ba2d3f</schemaIdAnn>
<ownerId>e3bd1480-09b5-4268-9126-6962238e9a1e</ownerId>
<schemaId>fd2941ad-276e-42b7-88fb-5054e8acdc8c</schemaId>
<ownerIdProd>5218f707-96de-4d4c-92c6-ebedd9ccbdbf</ownerIdProd>
<schemaIdProd>f50f2ac3-8e38-4733-adac-4817e3c58643</schemaIdProd>
<envClientId>PYJYF7XU017OGFH5RJ8Q</envClientId>
<secret>6MmE3bELLzO29r1ToG7LoVspWqanNJNGZCP0tG0N</secret>
<workspaceId>e3bd1480-09b5-4268-9126-6962238e9a1e</workspaceId>
<partnerId>b0f95322-a898-4af1-8fc1-9a8951d0c13a</partnerId>
<email>kukussfds@mailinator.com </email>
<alternativeWorkspaceId>81e15977-070a-4e68-8808-e2e6bb134f25</alternativeWorkspaceId>
<alternativeEnvClientId>PQSWUCNXVRL1LALUJBRJ</alternativeEnvClientId>
<alternativeSecret>VYpdpQ81n6p7i5C8FL2ni1RVOrHlD34ESxI1FW8U</alternativeSecret>
<serverDeployDelay>3500</serverDeployDelay>
</api>
</general>
我怎样才能防止这种情况?
解决方案
这是 XSLT 的概念示例。
XSLT 本身有些通用。它应该适用于任何没有名称空间的 XSLT。
我们将两个参数传递给 XSLT,即 XML 元素名称及其新值:
transformer.setParameter("elementToFind", "test2");
transformer.setParameter("elementValue", "Prophet");
输入 XML
<?xml version="1.0"?>
<test>
<abc value="10">data1</abc>
<bbc value="200">data2</bbc>
<abc value="20">
<test2>subdata1</test2>
</abc>
</test>
输出 XML
<?xml version='1.0' encoding='utf-8' ?>
<test>
<abc value="10">data1</abc>
<bbc value="200">data2</bbc>
<abc value="20">
<test2>Prophet</test2>
</abc>
</test>
爪哇
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.*;
public class Process3 {
public static void main(String[] args) {
String XSLTFILE = "e:\\Temp\\Process.xslt";
String INFILE = "e:/Temp/Input.xml";
String OUTFILE = "e:/Temp/Output.xml";
try {
// I/O
StreamSource input = new StreamSource(new File(INFILE));
StreamSource xslt = new StreamSource(new File(XSLTFILE));
StreamResult output = new StreamResult(new File(OUTFILE));
// Transformation
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer(xslt);
// XSLT parameters
transformer.setParameter("elementToFind", "test2");
transformer.setParameter("elementValue", "Prophet");
transformer.transform(input, output);
} catch (TransformerConfigurationException tce) {
tce.printStackTrace();
} catch (TransformerException te) {
te.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
XSLT
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="utf-8" indent="yes" omit-xml-declaration="no"/>
<xsl:strip-space elements="*"/>
<xsl:param name="elementToFind" select="'test2'"/>
<xsl:param name="elementValue" select="'Prophet'"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[local-name()=$elementToFind]">
<xsl:copy>
<xsl:value-of select="$elementValue"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
推荐阅读
- javascript - 是否有任何内置的 Javascript 函数用于排列?
- java - OpenJDK 平台二进制文件消耗过多内存
- python - 如何在python中显示弹出消息?
- deno - Deno 权限问题 - Uncaught PermissionDenied:网络访问
- amazon-web-services - 如果我丢失了 Amazon EC2 EBS 支持的实例的 SSH 密钥怎么办?
- google-cloud-platform - 如何更新现有服务帐号的角色 - Google Cloud Console
- flutter - Flutter 在 Firestore 中存储 TextStyle
- php - 正则表达式刚刚在 Bluehost 上崩溃了
- c# - 一段时间后杀死方法的进程.net core API
- github - GitHub API 对原始 IP 地址的速率限制