我有像这样的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”元素中将“Sueldo”添加到与“Nombre”和“Legajo”相同的级别。 “Sueldo”必须是“Legajo”x 2
我在上面的XML中看到的代码我附加了“Sueldo”,但它没有按照它应该缩进它,我使用propierties进行缩进(这个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());
}
}
}
先谢谢你们,我会感谢你们的帮助!
答案 0 :(得分:1)
假设您的输入文件与您显示但没有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
输出属性只是将结束</CNC>
标记移动到下一行,与开头标记对齐。要使自动缩进执行正确的操作,您需要从初始树中删除 all 仅空白文本节点。
或者,忘记自动缩进并自行完成 - 而不是将Sueldo
添加为CNC
的 last 子项(在该最终文本节点之后),而是添加紧跟在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>
您可以使用Java代码中的TransformerFactory
API或使用独立的命令行XSLT处理器运行。
答案 1 :(得分:0)
XML本质上没有定义任何缩进或漂亮的形式。如果您希望它“缩进”,则需要使用换行符和空格插入内容。在这种情况下,您需要在元素Legajo
之后和元素Sueldo
之前的内容。
根据我的口味,最好的策略是忽略来自XML文件的所有格式,并在人类消费之前立即使用广义的漂亮者。或者,更好的是,给他们好的XML编辑器。如果您拥有操作关注此详细信息的XML文件的每个程序,那么XML的大多数好处都会消失(并且会大量滥用)。
更新:注意到您使用元素CNC
来“定位”插入内容,而不是Legajo
。空格和换行内容需要紧接在元素CNC
之前(以及元素Sueldo
之后)。