如何使用 dom4j 在 XML 文件中的属性之间换行?
How to make newlines between attributes in XML file by using dom4j?
我想使用 java 生成以下格式的 xml 文件:
每个属性都应该在单独的行中。
<parameters>
<parameter
name="Tom"
city="York"
number="123"
/>
</parameters>
但是我只能在一行中获取所有属性
<parameters>
<parameter name="Tom" city="York" number="123"/>
</parameters>
我正在使用 dom4j,谁能告诉我该怎么做? dom4j 支持这种格式吗?
谢谢
一般来说,很少有 XML 序列化程序可以让您对输出格式进行这种级别的控制。
如果您指定选项 method=xml
、indent=yes
、saxon:line-length=20
,您可以使用 Saxon 序列化器获得类似的结果。 Saxon 序列化程序能够将 DOM4J 树作为输入。您将需要 Saxon-PE 或 -EE,因为它需要 Saxon 名称空间中的序列化参数。它仍然不是您想要的,因为第一个属性将与元素名称在同一行,而其他属性将在第一个属性的下方垂直对齐。
你不能用 XMLWriter
来做,除非你想实质性地重写主要逻辑。但是,由于 XMLWriter
也是 SAX ContentHandler
它可以使用 SAX 事件并将它们序列化为 XML,并且在这种操作模式下,XMLWriter
使用不同的代码路径更容易定制。下面的 sub class 几乎可以给你想要的,只是空元素不会使用短形式 <element/>
。也许可以通过进一步调整来解决这个问题。
static class ModifiedXmlWriter extends XMLWriter {
// indentLevel is private, need reflection to read it
Field il;
public ModifiedXmlWriter(OutputStream out, OutputFormat format) throws UnsupportedEncodingException {
super(out, format);
try {
il = XMLWriter.class.getDeclaredField("indentLevel");
il.setAccessible(true);
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
}
}
int getIndentLevel() {
try {
return il.getInt(this);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
@Override
protected void writeAttributes(Attributes attributes) throws IOException {
int l = getIndentLevel();
setIndentLevel(l+1);
super.writeAttributes(attributes);
setIndentLevel(l);
}
@Override
protected void writeAttribute(Attributes attributes, int index) throws IOException {
writePrintln();
indent();
super.writeAttribute(attributes, index);
}
}
public static void main(String[] args) throws Exception {
String XML = "<parameters>\n" +
" <parameter name=\"Tom\" city=\"York\" number=\"123\"/>\n" +
"</parameters>";
Document doc = DocumentHelper.parseText(XML);
XMLWriter writer = new ModifiedXmlWriter(System.out, OutputFormat.createPrettyPrint());
SAXWriter sw = new SAXWriter(writer);
sw.write(doc);
}
示例输出:
<?xml version="1.0" encoding="UTF-8"?>
<parameters>
<parameter
name="Tom"
city="York"
number="123"></parameter>
</parameters>
我想使用 java 生成以下格式的 xml 文件: 每个属性都应该在单独的行中。
<parameters>
<parameter
name="Tom"
city="York"
number="123"
/>
</parameters>
但是我只能在一行中获取所有属性
<parameters>
<parameter name="Tom" city="York" number="123"/>
</parameters>
我正在使用 dom4j,谁能告诉我该怎么做? dom4j 支持这种格式吗? 谢谢
一般来说,很少有 XML 序列化程序可以让您对输出格式进行这种级别的控制。
如果您指定选项 method=xml
、indent=yes
、saxon:line-length=20
,您可以使用 Saxon 序列化器获得类似的结果。 Saxon 序列化程序能够将 DOM4J 树作为输入。您将需要 Saxon-PE 或 -EE,因为它需要 Saxon 名称空间中的序列化参数。它仍然不是您想要的,因为第一个属性将与元素名称在同一行,而其他属性将在第一个属性的下方垂直对齐。
你不能用 XMLWriter
来做,除非你想实质性地重写主要逻辑。但是,由于 XMLWriter
也是 SAX ContentHandler
它可以使用 SAX 事件并将它们序列化为 XML,并且在这种操作模式下,XMLWriter
使用不同的代码路径更容易定制。下面的 sub class 几乎可以给你想要的,只是空元素不会使用短形式 <element/>
。也许可以通过进一步调整来解决这个问题。
static class ModifiedXmlWriter extends XMLWriter {
// indentLevel is private, need reflection to read it
Field il;
public ModifiedXmlWriter(OutputStream out, OutputFormat format) throws UnsupportedEncodingException {
super(out, format);
try {
il = XMLWriter.class.getDeclaredField("indentLevel");
il.setAccessible(true);
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
}
}
int getIndentLevel() {
try {
return il.getInt(this);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
@Override
protected void writeAttributes(Attributes attributes) throws IOException {
int l = getIndentLevel();
setIndentLevel(l+1);
super.writeAttributes(attributes);
setIndentLevel(l);
}
@Override
protected void writeAttribute(Attributes attributes, int index) throws IOException {
writePrintln();
indent();
super.writeAttribute(attributes, index);
}
}
public static void main(String[] args) throws Exception {
String XML = "<parameters>\n" +
" <parameter name=\"Tom\" city=\"York\" number=\"123\"/>\n" +
"</parameters>";
Document doc = DocumentHelper.parseText(XML);
XMLWriter writer = new ModifiedXmlWriter(System.out, OutputFormat.createPrettyPrint());
SAXWriter sw = new SAXWriter(writer);
sw.write(doc);
}
示例输出:
<?xml version="1.0" encoding="UTF-8"?>
<parameters>
<parameter
name="Tom"
city="York"
number="123"></parameter>
</parameters>