首页 > 解决方案 > 将 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 声明,则声明正在发送,所以我想,转换不起作用(因为不应该有一个声明?)。

标签: javaxmlmavenxslt

解决方案


好的,我设法通过最后三个编辑(将字符串转换为文档->解析文档->将文档转换回字符串)修复了它。我必须输入完整的路径

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();
    }
}

以防万一,未来的读者想要找到他们的错误。(对不起,我找不到它的链接)


推荐阅读