2015-10-22 90 views
1

我在数据库中存储xslt。我想调用另一个xslt中的模板,该模板也存储在数据库中。使用下面的示例代码,我能够正确运行xslt(考虑xsltOneStr是通过dao层来自数据库的xslt字符串,因此是xmlStr,这是xml将被解析)从数据库导入xslt

但是,如果我在xsltOne.xsl中使用,因为源xsltOne.xsl来自db并且被调用的xsltTwo.xsl也在DB中。很明显,在我的情况下使用导入在逻辑上是不正确的,因为我没有使用文件系统来获取xsl,而是来自数据库的字符流,但为了交谈,我使用了导入标记。

因此,自从xsl来自DB的问题应该用什么来代替xsl:import。我正在使用Java & xslt能够调用java方法。有什么办法可以使用java方法来调用驻留在db(xsltTwo.xsl)中的第二个xslt。如果xsltTwo.xsl在其中可以不能通过java方法调用,那么我至少可以在xsltOne.xsl中插入一个在xsltTwo中动态声明的模板

例如,我们可以调用java方法来使用java为xsl参数赋值如

同样,我们可以分配整个模板或使用java方法从另一个xslt调用一个xslt?

 Source xsltOne=new StreamSource(new StringReader(xsltOneStr)); 
     Source xml =new StreamSource(new StringReader(xmlStr)); 

     TransformerFactory factory = TransformerFactory.newInstance(); 
     Transformer transformer = factory.newTransformer(xsltOne); 

     StringWriter writer = new StringWriter(); 
     transformer.transform(xml, new StreamResult(writer)); 
+1

即使从数据库中读取XSLT中的'xsl:import',也没有问题。你的问题更多的是如何处理XSLT,包括Java中的另一个XSLT,无论数据库如何。你看过这个链接:http://stackoverflow.com/questions/3699860/resolving-relative-paths-when-loading -xslt文件? –

+1

@ user593029我刚刚注意到你问了很多问题,但很少[接受](https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work/5235#5235)回答。 – wero

回答

2

您可以通过提供URIResolver调整与document()xsl:importxsl:include完成XML样式表或文件的加载:

TransformerFactory factory = TransformerFactory.newInstance(); 
factory.setURIResolver(new MyURIResolver()); 
Transformer transformer = factory.newTransformer(xsltOne); 

现在在出厂的时候遇到xsl:import指令你的URIResolver通知提供输入样式表为Source。因此,您只需提供从数据库加载导入的样式表的URIResolver,并将其作为Source对象返回。

+0

我使用URIResolver在下面的链接中获得了一些更多信息,但这对解决相对路径或从类路径加载时有帮助。在任何一种情况下,xslt都是物理存在的,我的情况是第二个xslt来自数据库,所以我不确定URIResolver如何提供帮助。有人可以让我知道如何集成/导入第二个XSLT,这是来自数据库的字符串http://stackoverflow.com/questions/3699860/resolving-relative-paths-when-loading-xslt-files – user593029

+2

你有一些从数据库加载样式表的代码(这是你如何填充'xsltOneStr')。现在在您的URIResolver中调用相同的代码来加载导入的样式表。 – wero

+0

URIResolver返回一个Source对象。从数据库中读取样式表为字符串,将其包装在StringReader中,将StringReader包装在StreamSource中,并返回StreamSource(实现Source)。在StreamSource上调用setSystemId()可能也是一个好主意,因此它有一个已知的基本URI。 –

0

如果有人正在寻找如何创建解析器,我发现了一种方式,如下所述。 'MyResolver'类使用一个构造函数,它将xslt字符串作为参数&传递给'factory.setURIResolver'方法。在转换时,它调用resolve方法,依次传递使用来自db/file的xstl字符串形成的StreamSource obj。 (你可以构造具有取决于你逝去的& XSLT的数量更多,如果& else子句解决方法使用路径&名,如果更通用的制造)

线factory.setURIResolver(新MyResolver(xsltTwoStr));您可以看到它使用“xsltTwoStr”,它只是xsltOne中预期的导入xslt字符串。你可以使用dao层来调用xslt字符串(“xsltTwoStr”),或者直接加载文件本身。

 Source xsltOne=new StreamSource(new StringReader(xsltOneStr)); 
     Source xml =new StreamSource(new StringReader(xmlStr)); 


     TransformerFactory factory = TransformerFactory.newInstance(); 
     factory.setURIResolver(new MyResolver(xsltTwoStr)); 

     Transformer transformer = factory.newTransformer(xsltOne); 

     StringWriter writer = new StringWriter(); 
     transformer.transform(xml, new StreamResult(writer)); 



class MyResolver implements URIResolver { 
      String xsltStr; 

      public MyResolver(String xsltStr) { 
      this.xsltStr = xsltStr; 
      } 

      public Source resolve(String href,String base) { 

       return new StreamSource(new StringReader(this.xsltStr)); 
      } 
     }