目前,我正在尝试使用Java 9和javax开发一些代码。编辑xml文件的xml库(对于我的任务都是必需的),我在添加子节点时遇到了一些奇怪的问题。
这是XML文件:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<users>
</users>
我想编辑它构建如下内容:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<users>
<user>
<name>A name</name>
<last-name>Last Name</last-name>
<username>username</username>
</user>
</users>
现在,代码的第一次运行在<代码>
<users>
<user>
<name>name</name>
<last-name>lastname</last-name>
<username>username</username>
</user>
<user>
<name>name</name>
<last-name>lastname</last-name>
<username>username</username>
</user>
</users>
这是运行程序2次后生成的XML。如您所见,它在<代码>
在更新文件之前想知道这些节点的内容是什么,我写了下一段代码:
int i=0;
while (root.getChildNodes().item(i)!=null){
Node aux = root.getChildNodes().item(i);
System.out.println("Node text content: ".concat(aux.getTextContent()));
i++;
}
第一次执行:
Node text content:
Node text content: namelastnameusername
第二次执行:
Node text content:
Node text content:
name
lastname
username
Node text content:
Node text content: namelastnameusername
第三次执行
Node text content:
Node text content:
name
lastname
username
Node text content:
Node text content:
name
lastname
username
Node text content:
Node text content: namelastnameusername
最后,这是Java代码:
private static void saveUser(String firstName, String lastName, String username){
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new File(databaseFile));
Element root = doc.getDocumentElement();
root.normalize();
// build user node
Element userNode = doc.createElement("user");
Element nameNode = doc.createElement("name");
Element lastNameNode = doc.createElement("last-name");
Element usernameNode = doc.createElement("username");
//build structure
nameNode.appendChild(doc.createTextNode(firstName));
lastNameNode.appendChild(doc.createTextNode(lastName));
usernameNode.appendChild(doc.createTextNode(username));
userNode.appendChild(nameNode);
userNode.appendChild(lastNameNode);
userNode.appendChild(usernameNode);
root.appendChild(userNode);
//write the updated document to file or console
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File(databaseFile));
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.transform(source, result);
}catch (SAXException | ParserConfigurationException | IOException | TransformerException e1) {
e1.printStackTrace();
}
}
我能找到的唯一解决方案是在生成XML后删除空行,但我认为这不是一个合适的解决方案,我想先找到一些替代方案。
对如何解决这个问题有什么建议吗?
您的解决方案和下面的建议对我来说都很好,请尝试使用此测试用例,
public static void main(String[] args) {
saveUser("test one", "test two", "test three");
}
private static void saveUser(String firstName, String lastName, String username){
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new File("second.xml"));
Element root = doc.getDocumentElement();
root.normalize();
// build user node
Element userNode = doc.createElement("user");
Element nameNode = doc.createElement("name");
Element lastNameNode = doc.createElement("last-name");
Element usernameNode = doc.createElement("username");
userNode.appendChild(nameNode).setTextContent(firstName); //set the text content
userNode.appendChild(lastNameNode).setTextContent(lastName);
userNode.appendChild(usernameNode).setTextContent(username);
root.appendChild(userNode);
//write the updated document to file or console
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File("second.xml"));
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.transform(source, result);
}catch (Exception e) {
e.printStackTrace();
}
}
第二xml(执行前)
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<users>
</users>
第二xml(第一次执行)
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<users>
<user>
<name>test one</name>
<last-name>test two</last-name>
<username>test three</username>
</user>
</users>
second.xml(第二次执行)
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<users>
<user>
<name>test one</name>
<last-name>test two</last-name>
<username>test three</username>
</user>
<user>
<name>test one</name>
<last-name>test two</last-name>
<username>test three</username>
</user>
</users>
second.xml(第三次处决)
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<users>
<user>
<name>test one</name>
<last-name>test two</last-name>
<username>test three</username>
</user>
<user>
<name>test one</name>
<last-name>test two</last-name>
<username>test three</username>
</user>
<user>
<name>test one</name>
<last-name>test two</last-name>
<username>test three</username>
</user>
</users>
导入类,
import java.io.File;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.parsers.DocumentBuilder; // missing import class
import org.w3c.dom.Document;
import org.w3c.dom.Element;
简而言之:实际上,在Java9中,您只能在xml生成后或从文件中解析xml后删除空行,例如:
private void clearBlankLine(Element element) {
NodeList childNodes = element.getChildNodes();
for (int index = 0; index < childNodes.getLength(); index++) {
Node item = childNodes.item(index);
if (item.getNodeType() != 1 && System.lineSeparator()
.equals(item.getNodeValue())) {
element.removeChild(item);
} else {
if (item instanceof Element) {
clearBlankLine((Element) item);
}
}
}
}
然后使用root
元素调用它。
详细信息:
在xml生成流程中,每个元素解析有三个生命周期:start Element
、parse
、endElement
。而indent
功能是在start Element
范围内实现的。缩进也会在文档中添加空行。
java 8中的调用堆栈与java 9不同:
在Java 8中:ToStream#startElement-
在Java 9中:
ToStream#startElement-
当我们打开缩进功能时,flushCharactersBuffer也会缩进,例如:
transformer。setOutputProperty(OutputKeys.INDENT,“是”)
调用方法的条件:flushCharactersBuffer和方法:
indent几乎相同。
这意味着在Java 9中,这将为每个需要缩进的元素添加两行新行,结果显示为空行。
我怀疑是变压器添加了空行。
不要使用默认的转换器(transformerFactory.newTransformer()
),而是尝试传入设置了xsl:strip space的XSLT(transformerFactory.newTransformer(新的流源(新文件(路径到XSLT\u文件)))
)。。。
XSLT文件
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
今天我开始学习ReactJS,一个小时后我就开始面对这个问题。。我想在页面上的div中插入一个有两行的组件。下面是我正在做的一个简化示例。 我有一个html: 渲染功能如下: 下面我调用渲染: 生成的HTML如下所示: 我不是一个非常高兴的问题,这个问题迫使我将所有内容都打包在一个div“DeadSimpleComponent”中。在没有显式DOM操作的情况下,最好且简单的解决方法是什么? 201
问题内容: 我正在多线程环境中聚合键的多个值。密钥未知。我以为我会做这样的事情: 我看到的问题是,每次运行此方法时,我都需要创建一个新的实例,然后将其丢弃(在大多数情况下)。这似乎是对垃圾收集器的不合理滥用。是否有更好的,线程安全的方法来初始化这种结构而不必使用该方法?我对使该方法不返回新创建的元素的决定感到惊讶,并且对缺少除非被要求(可以这么说)实例化实例的延迟的方法感到惊讶。 问题答案: Ja
此外,我不想将开发人员从ProjectManager转移到JavaProjectManager,因为我有更多从ProjectManager扩展的类,需要开发人员。
我试图比较两个不同对象的名称,但是当使用方法将一个项目与null进行比较时,我一直得到异常。我尝试了很多方法,包括other.equals(哈哈)、haha.equals(其他)等等,但都失败了。
本文向大家介绍java 避免出现NullPointerException(空指针)的方法总结,包括了java 避免出现NullPointerException(空指针)的方法总结的使用技巧和注意事项,需要的朋友参考一下 java 避免出现NullPointerException(空指针)的方法总结 Java应用中抛出的空指针异常是解决空指针的最好方式,也是写出能顺利工作的健壮程序的关键。俗话说“预
问题内容: 我想创建一个XML,其中用替换空白。但是Java-Transformer逃避了&符,因此输出为 这是我的示例代码: 这是我的示例代码的输出: 有任何解决或避免的想法吗?非常感谢! 问题答案: 将文本内容直接设置为所需的字符,如有必要,序列化程序将为您转义: