编辑现在我知道为什么人们使用字符串构建器,使用JAXB是一件痛苦而且非常耗时的事情,至少对我来说这是因为我有一个非常复杂的XML来生成。感谢帮助:)
我有一个收集用户数据的java应用程序。
我还创建了一个模板XSL。现在我被卡住了。我下一步要做什么?我应该使用java代码来创建XML吗?如果是这样,我创建了什么样的XML,我需要在最后严格要求我的HTML。很抱歉,如果这是重复的,我无法找到任何内容,而且我对XML完全陌生。还有一个问题是,这是xml的有效语法:
StringBuilder sb = new StringBuilder(500);
sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
sb.append("<report version=\"").append(reportVersion).append("\" generated=\"").append(scanVersion).append("\">\r\n");
sb.append("</report >");
输出为
<?xml version="1.0" encoding="UTF-8"?>
<report version="alpha" generated="1">
</report >
我现在如何使用java获取版本并生成?
我也明白有xslt 1.0和2.0,我应该选哪一个?
修改
我正在玩JAXB并获得了以下两个课程。
import java.util.ArrayList;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Report
{
String title;
String reportBy;
String reportFor;
String scanDate;
String scanVersion;
String reportDate;
String reportVersion;
String desc;
ArrayList<String> alertSeverity;
ArrayList<String> alertDetails;
public String getTitle()
{
return title;
}
@XmlElement
public void setTitle(String title)
{
this.title = title;
}
public String getBy()
{
return reportBy;
}
@XmlElement
public void setBy(String reportBy)
{
this.reportBy = reportBy;
}
public String getFor()
{
return reportFor;
}
@XmlElement
public void setFor(String reportFor)
{
this.reportFor = reportFor;
}
public String getScanDate()
{
return scanDate;
}
@XmlElement
public void setScanDate(String scanDate)
{
this.scanDate = scanDate;
}
public String getScanVersion()
{
return scanVersion;
}
@XmlElement
public void setScanVersion(String scanVersion)
{
this.scanVersion = scanVersion;
}
public String getReportDate()
{
return reportDate;
}
@XmlElement
public void setReportDate(String reportDate)
{
this.reportDate = reportDate;
}
public String getReportVersion()
{
return reportVersion;
}
@XmlElement
public void setReportVersion(String reportVersion)
{
this.reportVersion = reportVersion;
}
public String getDesc()
{
return reportVersion;
}
@XmlElement
public void setDesc(String desc)
{
this.desc = desc;
}
}
和主要:
import java.io.File;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
public class JAXBExample {
public static void main(String[] args) {
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date date = new Date();
Report report = new Report();
report.setTitle("my custom title");
report.setBy("hans");
report.setFor("pepe");
report.setScanDate(dateFormat.format(date));
report.setScanVersion("orignal version");
report.setReportDate(dateFormat.format(date));
report.setReportVersion("version is alpha");
report.setDesc("some random desc");
try {
File file = new File("C:\\Users\\testuser\\Desktop\\file.xml");
JAXBContext jaxbContext = JAXBContext.newInstance(Report.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
// output pretty printed
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
jaxbMarshaller.marshal(report, file);
jaxbMarshaller.marshal(report, System.out);
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
我只是不知道如何处理我需要循环添加元素的ArrayList
等。
目前的输出是:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<report>
<by>hans</by>
<desc>version is alpha</desc>
<for>pepe</for>
<reportDate>2016/02/28 18:36:33</reportDate>
<reportVersion>version is alpha</reportVersion>
<scanDate>2016/02/28 18:36:33</scanDate>
<scanVersion>orignal version</scanVersion>
<title>my custom title</title>
</report>
现在我有两个应该进入此报告的数组,不知道如何处理它们。不仅如此,如果用户没有选择要进入的项目,那么它不应该这样做。因此,xml永远不会相同,一个属性可能不存在,有时也可能存在。这有意义吗?
编辑2:我需要的是这样的东西
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<report>
<by>hans</by>
<desc>version is alpha</desc>
<for>pepe</for>
<reportDate>2016/02/28 18:36:33</reportDate>
<reportVersion>version is alpha</reportVersion>
<scanDate>2016/02/28 18:36:33</scanDate>
<scanVersion>orignal version</scanVersion>
<title>my custom title</title>
<site host="1" name="1" port="80" ssl="true">
<items>
<item>
<name>item 1</name>
<id>1</id>
</item>
<item>
<name>item 2</name>
<id>1</id>
</item>
</items>
</site>
<site host="2" name="2" port="80" ssl="true">
<items>
<item>
<name>item 1</name>
<id>1</id>
</item>
<item>
<name>item 2</name>
<id>1</id>
</item>
</items>
</site>
</report>
所有这些都包含在ArrayList
我如何使用JAXB创建这个xml?任何输入将不胜感激:)
答案 0 :(得分:1)
创建一个XSD,表示XML中所需的结构。如果您不熟悉XSD,我建议您阅读this tutorial。
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xs:element name="report">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" name="by" type="xs:string" />
<xs:element minOccurs="0" maxOccurs="1" name="desc" type="xs:string" />
<xs:element minOccurs="0" maxOccurs="1" name="for" type="xs:string" />
<xs:element minOccurs="0" maxOccurs="1" name="reportDate"
type="xs:dateTime" />
<xs:element minOccurs="0" maxOccurs="1" name="reportVersion"
type="xs:string" />
<xs:element minOccurs="0" maxOccurs="1" name="scanDate"
type="xs:dateTime" />
<xs:element minOccurs="0" maxOccurs="1" name="scanVersion"
type="xs:string" />
<xs:element minOccurs="0" maxOccurs="1" name="title"
type="xs:string" />
<xs:element minOccurs="0" maxOccurs="unbounded" ref="site" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="site">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="1" maxOccurs="1" ref="items" />
</xs:sequence>
<xs:attribute use="required" name="host" type="xs:string" />
<xs:attribute use="required" name="name" type="xs:string" />
<xs:attribute use="required" name="port" type="xs:string" />
<xs:attribute use="required" name="ssl" type="xs:string" />
</xs:complexType>
</xs:element>
<xs:element name="items">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="item" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="item">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="1" maxOccurs="1" name="name" type="xs:string" />
<xs:element minOccurs="1" maxOccurs="1" name="id" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
注1:类型xs:dateTime
仅允许在ISO 8601格式化的日期时间。 Source W3C。如果你真的想要一个自定义日期时间格式,你将不得不根据字符串编写自己的模式(因此失去了日期验证的全部功能)。
注意2:正如您所注意到的,xs:element
有一个minOccurs
和maxOccurs
可以调整,如果你知道一个元素是强制性的。
您可以使用工具XJC(与Java捆绑在一起)自动生成相应的Java类。 JAXB可以直接使用这些类将数据序列化为所需的XML格式。
以下命令应该可以解决问题:
/path/to/jdk/bin/xjc -d /path/to/output/folder -p your.package.name /path/to/report.xsd
应生成以下类(样本)
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"name",
"id"
})
@XmlRootElement(name = "item")
public class Item {
@XmlElement(required = true)
protected String name;
@XmlElement(required = true)
protected String id;
public String getName() {
return name;
}
public void setName(String value) {
this.name = value;
}
public String getId() {
return id;
}
public void setId(String value) {
this.id = value;
}
}
注意:生成的类是简单的POJO,我不鼓励直接使用(只有JAXB可以使用)。如果您已经根据业务构建了Report
类,则可以创建一些XmlAdapter来映射业务对象和JAXB-POJO。
使用报告数据填写这些对象:
Item i1 = new Item();
i1.setName("item 1");
i1.setId("1");
Item i2 = new Item();
i2.setName("item 2");
i2.setId("2");
Items items = new Items();
items.getItem().addAll(Arrays.asList(i1, i2));
Site s1 = new Site();
s1.setHost("1");
s1.setName("1");
s1.setPort("80");
s1.setSsl("true");
s1.setItems(items);
Site s2 = new Site();
s2.setHost("2");
s2.setName("2");
s2.setPort("80");
s2.setSsl("true");
s2.setItems(items);
Report r = new Report();
r.setBy("hans");
r.setDesc("version is alpha");
r.setFor("pepe");
r.setReportDate(DatatypeFactory.newInstance().newXMLGregorianCalendar("2016-02-28T18:36:33"));
r.setReportVersion("version is alpha");
r.setScanDate(DatatypeFactory.newInstance().newXMLGregorianCalendar("2016-02-28T18:36:33"));
r.setScanVersion("original version");
r.setTitle("my custom title");
r.getSite().addAll(Arrays.asList(s1, s2));
注意:如果你有xmlAdapters,这一步就变得不那么乏味了。
将它们保存为XML
JAXBContext jaxbContext = JAXBContext.newInstance(Report.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
jaxbMarshaller.marshal(r, new File("report.xml"));
注意:report.xml将完全采用您需要的格式。
在HTML中转换XML
StreamResult result = new StreamResult(new File("output.html"));
StreamSource source = new StreamSource(new File("report.xml"));
StreamSource xslt = new StreamSource(new File("transform.xslt"));
Transformer transformer = TransformerFactory.newInstance().newTransformer(xslt);
transformer.transform(source, result);