我有一个这样的xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Empleado>
<ConsultorTecnico>
<Nombre>Pablo</Nombre>
<Legajo antiguedad="4 meses">7778</Legajo>
</ConsultorTecnico>
<CNC>
<Nombre>Brian</Nombre>
<Legajo antiguedad="1 año, 7 meses">2134</Legajo>
<Sueldo>4268.0</Sueldo>
</CNC>
</Empleado>
我想要的是读取 XML 并在元素“CNC”中附加与“Nombre”和“Legajo”相同级别的“Sueldo”。 “Sueldo”必须是“Legajo”x 2
我的代码附加了“Sueldo”,正如您在上面的 XML 中看到的那样,但它没有按应有的方式缩进,我使用属性来缩进(此 XML 的创建方式相同,使用 DOM)
public class Main
{
public static void main(String[] args)
{
try
{
File xml = new File("C:\\Empleado.xml");
if (xml.exists() == true)
{
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(xml);
String legajo = doc.getElementsByTagName("Legajo").item(1).getFirstChild().getNodeValue();
Element sueldo = doc.createElement("Sueldo");
Node valorSueldo = doc.createTextNode(String.valueOf(Float.valueOf(legajo)*2));
sueldo.appendChild(valorSueldo);
Node cnc = doc.getElementsByTagName("CNC").item(0);
cnc.appendChild(sueldo);
DOMSource source = new DOMSource(doc);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer t = tf.newTransformer();
t.setOutputProperty(OutputKeys.INDENT, "yes");
t.setOutputProperty("{http://xml.apache.org/xslt}indent-amount","2");
FileOutputStream fos = new FileOutputStream("C:\\Empleado.xml");
StreamResult sr = new StreamResult(fos);
t.transform(source,sr);
}
else
throw new Exception("No hay archivo XML con ese nombre en el directorio");
}
catch (Exception e)
{
System.out.println(e.getMessage());
}
}
提前谢谢你们,我会很感激这里的帮助!
最佳答案
假设您的输入文件与您显示的输出相同,但没有 Sueldo
元素,然后是初始的 CNC
就 DOM 而言,元素有 五个 个子节点
<CNC>
之间的空白文本节点(换行符和四个空格)和<Nombre>
Nombre
元素节点</Nombre>
之间的空白文本节点(换行符和四个空格)和<Legajo
Legajo
元素节点</Legajo>
之间的空白文本节点(换行符和两个 空格)和</CNC>
您正在插入 Sueldo
最终文本节点之后的元素,它产生
<CNC>
<Nombre>Brian</Nombre>
<Legajo antiguedad="1 año, 7 meses">2134</Legajo>
<Sueldo>4268.0</Sueldo></CNC>
和 INDENT
output 属性只是移动结束 </CNC>
标记到下一行,与开头的一行对齐。要让自动缩进做正确的事情,您需要从初始树中删除所有纯空白文本节点。
或者,忘记自动缩进并自己做 - 而不是添加 Sueldo
作为 CNC
的最后一个 child (在最后一个文本节点之后),而是在 Legajo
之后立即添加一个换行符和四个空格的文本节点。 (即在最后一个文本节点之前)然后添加 Sueldo
之后的元素。
作为完全替代的方法,我会考虑在 XSLT 中进行转换而不是使用 DOM API
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!-- ignore whitespace-only text nodes in the input -->
<xsl:strip-space elements="*"/>
<!-- and re-indent the output -->
<xsl:output method="xml" indent="yes" />
<!-- Copy everything verbatim except where otherwise specified -->
<xsl:template match="@*|node()">
<xsl:copy><xsl:apply-templates select="@*|node()" /></xsl:copy>
</xsl:template>
<!-- For CNC elements, add a Sueldo as the last child -->
<xsl:template match="CNC">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
<Sueldo><xsl:value-of select="Legajo * 2" /></Sueldo>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
您可以使用 TransformerFactory
运行它来自 Java 代码或使用独立命令行 XSLT 处理器的 API。
关于java - 使用保持格式的 DOM 在 XML 中追加元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18407321/