2012-04-26 56 views
0

我用Java编写RESTful Web服务。 的想法是“砍掉”的XML文档,并剥离了所有的联合国需要的内容(〜98%),只留下我们感兴趣的标签,同时保持文档的结构,这是如下(我不能为保密原因,实际的XML内容):RESTFUL GlassFish的XML XSLT样式表的Java转换所产生的空输出

<sear:SEGMENTS xmlns="http://www.exlibrisgroup.com/xsd/primo/primo_nm_bib" xmlns:sear="http://www.exlibrisgroup.com/xsd/jaguar/search"> 
    <sear:JAGROOT> 
     <sear:RESULT> 
     <sear:DOCSET IS_LOCAL="true" TOTAL_TIME="176" LASTHIT="9" FIRSTHIT="0" TOTALHITS="262" HIT_TIME="11"> 
      <sear:DOC SEARCH_ENGINE_TYPE="Local Search Engine" SEARCH_ENGINE="Local Search Engine" NO="1" RANK="0.086826384" ID="2347460"> 
       [ 
       <PrimoNMBib> 
        <record> 
        <display> 
         <title></title> 
        </display> 
        <sort> 
         <author></author> 
        </sort> 
        </record> 
       </PrimoNMBib> 
       ] 
      </sear:DOC> 
     </sear:DOCSET> 
     </sear:RESULT> 
    </sear:JAGROOT> 
</sear:SEGMENTS> 

当然,这仅仅是标签我们感兴趣的结构 - 有数百个标签,但它们是不相关的。

的方括号([])不是XML的一部分,并指示该元素是儿童的列表元素和出现多于一次的 - 每从REST式服务的搜索的匹配之一。

这就是说,包含XSLT样式表我的Java代码如下:

import java.io.StringReader; 
    import java.io.StringWriter; 

    import javax.xml.transform.Transformer; 
    import javax.xml.transform.TransformerException; 
    import javax.xml.transform.TransformerFactory; 
    import javax.xml.transform.TransformerFactoryConfigurationError; 
    import javax.xml.transform.stream.StreamResult; 
    import javax.xml.transform.stream.StreamSource; 

    public String cutXML() throws TransformerFactoryConfigurationError, TransformerException 
    { 

     String xmlSourceResource = this.xml; // where this.xml is the full XML string of structure as presented above 

     String xsltResource = 
     "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" xmlns:sear=\"http://www.exlibrisgroup.com/xsd/jaguar/search\">" + 

     " <xsl:output method=\"xml\" version=\"1.0\" omit-xml-declaration=\"no\" encoding=\"UTF-8\" indent=\"yes\"/>" + 
     " <xsl:strip-space elements=\"*\"/>" + 

     " <sear:WhiteList>" + 
     "  <name>title</name>" + 
     "  <name>author</name>" +     
     " </sear:WhiteList>" + 

     " <xsl:template match=\"node()|@*\">" + 
     "  <xsl:copy>" + 
     "   <xsl:apply-templates select=\"node()|@*\"/>" + 
     "  </xsl:copy>" + 
     " </xsl:template>" + 

     " <xsl:template match=\"*[not(descendant-or-self::*[name()=document('')/*/sear:WhiteList/*])]\"/>" + 

     "</xsl:stylesheet>"; 

     StringWriter xmlResultResource = new StringWriter(); // where the transformed/stripped-down XML will be written 

     Transformer xmlTransformer = TransformerFactory.newInstance().newTransformer(new StreamSource(new StringReader(xsltResource))); // create transformer object with XSLT given 

     xmlTransformer.transform(new StreamSource(new StringReader(xmlSourceResource)), new StreamResult(xmlResultResource)); // transform XML with transformer and write into result StringWriter 

     return xmlResultResource.getBuffer().toString(); // return transformed XML string 

    } 

不幸的是,当我在服务器上运行它,我得到的是一个空源的空白页面,仿佛转换的结果是一个空字符串。

服务器的日志文件中第一次给了以下信息:

[#|2012-04-26T18:26:24.967+0000|INFO|glassfish3.1.2|com.sun.jersey.api.core.PackagesResourceConfig|_ThreadID=23;_ThreadName=Thread-2;|Scanning for root resource and provider classes in the packages: dk.kb.mobileservice|#] 

    [#|2012-04-26T18:26:24.969+0000|INFO|glassfish3.1.2|com.sun.jersey.api.core.ScanningResourceConfig|_ThreadID=23;_ThreadName=Thread-2;|Root resource classes found: class dk.kb.mobileservice.Middle|#] 

    [#|2012-04-26T18:26:24.970+0000|INFO|glassfish3.1.2|com.sun.jersey.api.core.ScanningResourceConfig|_ThreadID=23;_ThreadName=Thread-2;|No provider classes found.|#] 

    [#|2012-04-26T18:26:24.978+0000|INFO|glassfish3.1.2|com.sun.jersey.server.impl.application.WebApplicationImpl|_ThreadID=23;_ThreadName=Thread-2;|Initiating Jersey application, version 'Jersey: 1.11 12/09/2011 10:27 AM'|#] 

    [#|2012-04-26T18:26:25.192+0000|INFO|glassfish3.1.2|javax.enterprise.system.container.web.com.sun.enterprise.web|_ThreadID=23;_ThreadName=Thread-2;|WEB0671: Loading application [kb2] at [/kb2]|#] 

    [#|2012-04-26T18:26:25.200+0000|INFO|glassfish3.1.2|javax.enterprise.system.tools.admin.org.glassfish.deployment.admin|_ThreadID=23;_ThreadName=Thread-2;|kb2 was successfully deployed in 2,293 milliseconds.|#] 

    [#|2012-04-26T18:26:46.263+0000|SEVERE|glassfish3.1.2|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=20;_ThreadName=Thread-2;|SystemId Unknown; Line #0; Column #0; java.lang.NullPointerException |#] 

    [#|2012-04-26T18:31:09.772+0000|SEVERE|glassfish3.1.2|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=21;_ThreadName=Thread-2;|SystemId Unknown; Line #0; Column #0; java.lang.NullPointerException |#] 

,现在返回了以下问题:

[#|2012-04-27T00:05:07.731+0000|SEVERE|glassfish3.1.2|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=21;_ThreadName=Thread-2;|Error on line 1 column 1 of file:/root/webglassfish3/glassfish/domains/domain1/config/: SXXP0003: Error reported by XML parser: Content is not allowed in prolog.|#] 

    [#|2012-04-27T00:05:07.732+0000|SEVERE|glassfish3.1.2|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=21;_ThreadName=Thread-2;|Recoverable error on line 1 SXXP0003: org.xml.sax.SAXParseException: Content is not allowed in prolog.|#] 

我通过浏览器测试的XML文件,并把它改造,并它工作,所以我不认为这是XML的,也不是XSLT样式表的错误......这似乎是一个Java问题。

当我运行在GlassFish之外的整个XML上面的Java代码,我得到以下错误:

Exception in thread "main" java.lang.VerifyError: (class: GregorSamsa$0, method: test signature:   (IIIILcom/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet;Lcom/sun/org/apache/xml/internal/dtm/DTMAxisIterator;)Z) Incompatible type for getting or setting field 
     at GregorSamsa.applyTemplates() 
     at GregorSamsa.applyTemplates() 
     at GregorSamsa.transform() 
     at   com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet.transform(AbstractTranslet.java:609) 
     at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:729) 
     at   com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:340) 
     at XML2JSON.cutXML(XML2JSON.java:105) 
     at XML2JSON.main(XML2JSON.java:31) 
+0

你说你通过浏览器把它改造 - 这是否意味着你已经成功地在Java代码之外的相同文件运行相同的XSLT转换?如果是这样,这听起来像XSLT“引擎”的差异。疯狂猜测 - 尝试在Java字符串的前面插入<?xml version =“1.0”?>'。 – 2012-04-27 13:51:42

+0

Hi Rob,是的,我在我的xml开头放了<?xml-stylesheet type =“text/xsl”href =“test.xsl”?>,其中test.xsl是样式表,并将其应用于Google Chrome和它工作得很好......通过java字符串,你的意思是我的xml字符串或xsl字符串? – Piotr 2012-04-27 15:15:23

+0

我的意思是XSL字符串 - 毕竟它也是XML,所以我可以想象一个XSL机制在XSL文档的开头需要声明,但另一个不需要它。 – 2012-04-27 16:50:13

回答

0

Content is not allowed in prolog.通常意味着你有你的XML开始前的内容。 XML解析器希望看到此XML声明:<?xml version="1.0"?>,或者如果被忽略,那么仅仅是文档元素的开始(即<sear:SEGMENTS>

打印/日志的this.xml内容,并确认不存在任何前导空格字符或XML声明或文档元素之前的其他内容。

+0

嗨Mads, 谢谢,但我已经检查,并没有空白之前的文件的开始... – Piotr 2012-04-27 01:09:18

+0

物理文件,或您的'this.xml'变量?你确定你的'this.xml'包含XML内容吗?该错误消息引用'file:/ root/webglassfish3/glassfish/domains/domain1/config /'。这是来自你的代码的另一部分的错误,或者你可以在'String xmlSourceResource = this.xml;'中分配错误的信息吗? – 2012-04-27 10:49:59

+0

Hey Mads,this.xml只是一个字符串,包含由RESTFUL服务对搜索查询的响应生成的XML内容。我检查过,它确实包含XML ... – Piotr 2012-04-27 11:31:09