java - 将 XML 发送到 RESTful WebService 的网站时,XSL 似乎不起作用。我怎样才能解决这个问题?
问题描述
我目前正在编写一个 WebService 来从大学的不同餐厅网站获取食物。我现在可以将我的 DB 输出解析为 XML 并将这个 XML 发送到我的输出页面。现在我想把它变成一个 HTML 表格。我的 XSL 已经完成并且可以工作了,但是在发送我的 XML 时我无法让它工作。
这是我的 XML:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="/resources/transHTML.xsl"?>
<results>
<item>
<FoodID>1</FoodID>
<RestID>1</RestID>
...
</item>
</results>
我正在使用 Maven,我的结构如下所示:
Project-|
|-src-main-java-|-main-crawler-java-classes
| |-resources-transHTML.xsl
|
|-web|-WEB-INF-web.xml
| |-index.html (my page)
|
|-pom.xml
那是我的 web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>randoheld</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>crawl</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>crawl</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>randoheld</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
我在用着
Response response = Response.status(200).type(MediaType.TEXT_XML).entity(output).build();
得到我的回复,然后立即返回。目前,我得到了 XML-Node-Values(所以 XML 没有转换)。我想,问题是我通向 xsl 的路径,我已经用我的 CSS 遇到了这个问题,在无法解决它之后将它编码到我的 index.jsp 中。
也许有人可以帮助我,在此先感谢。
编辑:
这是我对 ResultSet 的转换:
public static String convertToXML(ResultSet rs) {
StringBuffer xmlArray = null;
try {
xmlArray = new StringBuffer("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<?xml-stylesheet type=\"text/xsl\" href=\"${pageContext.request.contextPath}/resources/transHTML.xsl\"?>\n<results>\n");
int total_rows = rs.getMetaData().getColumnCount();
for (int i = 0; i < total_rows; i++) {
xmlArray.append("<col>" + rs.getMetaData().getColumnLabel(i+1) + "</col>\n");
}
while (rs.next()) {
xmlArray.append("<item>\n");
for (int i = 0; i < total_rows; i++) {
xmlArray.append("<" + rs.getMetaData().getColumnLabel(i + 1)
+ ">" + rs.getObject(i + 1) + "</" + rs.getMetaData()
.getColumnLabel(i + 1) + ">\n");
}
xmlArray.append("</item>\n");
}
xmlArray.append("</results>");
} catch (SQLException se2) {
}return xmlArray.toString();
}
我还将我的 xsl 切换为 web-resources-transHTML.xsl。我的 POM 有以下代码,我在论坛中找到:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
</manifest>
</archive>
<webResources>
<resource>
<!-- this is relative to the pom.xml directory -->
<directory>${project.basedir}/web/resources</directory>
</resource>
</webResources>
<warName>mywar</warName>
</configuration>
</plugin>
</plugins>
</build>
编辑 2:我注意到,我的转换返回一个字符串,它不应该是一个真正的 XML 对吗?所以我把那个字符串变成了一个文档:
public static Document xmlToDoc(String xml) {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder;
Document xmlDoc = null;
try
{
builder = factory.newDocumentBuilder();
xmlDoc = builder.parse(new InputSource(new StringReader(xml) ) );
} catch (Exception e) {
e.printStackTrace();
}
return xmlDoc;
}
在用我的 .xsl 转换它之前:
public static Document transformXML(Document xmlDoc){
Document resultDoc = null;
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder db = dbf.newDocumentBuilder();
Document xslt = db.parse("resources/transHTML.xsl");
Source xmlSource = new DOMSource(xmlDoc);
Source xsltSource = new DOMSource(xslt);
DOMResult result = new DOMResult();
TransformerFactory transFact
= TransformerFactory.newInstance();
Transformer trans = transFact.newTransformer(xsltSource);
trans.transform(xmlSource, result);
resultDoc = (Document) result;
} catch (IOException e) {
e.printStackTrace();
} catch (TransformerConfigurationException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (TransformerException e) {
e.printStackTrace();
}
return resultDoc;
}
最后将其放回输出字符串(因为应该编译 HTML 文本对吗?):
public static String BackToString(Document xmlDoc) {
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer;
try {
transformer = tf.newTransformer();
// below code to remove XML declaration
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
StringWriter writer = new StringWriter();
transformer.transform(new DOMSource(xmlDoc), new StreamResult(writer));
String output = writer.getBuffer().toString();
return output;
} catch (TransformerException e) {
e.printStackTrace();
}
return null;
}
但是它返回一个空字符串。如果我删除代码,删除 XML 声明,则声明正在发送,所以我想,转换不起作用(因为不应该有一个声明?)。
解决方案
好的,我设法通过最后三个编辑(将字符串转换为文档->解析文档->将文档转换回字符串)修复了它。我必须输入完整的路径
Document xslt = db.parse("pathToXsl");
所以错误确实是 XML 转换。
但是我对此并不满意,因为在现实世界的场景中,每个人都可以看到我的系统路径。我使用以下代码检查,哪个文档是空的:
public static void printDocument(Document doc, OutputStream out){
TransformerFactory tf = TransformerFactory.newInstance();
try {
Transformer transformer = tf.newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
transformer.setOutputProperty(OutputKeys.METHOD, "xml");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
transformer.transform(new DOMSource(doc),
new StreamResult(new OutputStreamWriter(out, "UTF-8")));
} catch (TransformerConfigurationException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (TransformerException e) {
e.printStackTrace();
}
}
以防万一,未来的读者想要找到他们的错误。(对不起,我找不到它的链接)
推荐阅读
- android - 如何将 Android Studio 项目迁移到基于 Android.mk 的项目,以作为 AOSP 构建的一部分构建?
- azure - 用于 VM 关机/开机通知的 Azure Logicapps
- python - yalm.dump python中的特殊字符
- entity-framework - 如何在具有多对多关系的 Entity Framework Core 5 Web API 中使用 HttpPost
- python - 检查图像是否透明
- django - Django中的页面范围变量
- c++ - 在源文件中声明函数模板时是否应该防止 ODR 违规?
- c# - 在 TextBox 控件的选择周围插入文本
- python - 无需任何外部库的 Python 图像裁剪
- python - Opencv轮廓区域返回错误结果