2010-09-13 39 views
11

tôi cần phải làm một biến đổi XSL sử dụng Apache FOP và tôi đã có mã như thế này:Giải quyết đường dẫn tương đối khi tải file XSLT

//Setup FOP 
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, out); 
//Setup Transformer 
Source xsltSrc = new StreamSource(new File(xslPath)); 
Transformer transformer = tFactory.newTransformer(xsltSrc); 

//Make sure the XSL transformation's result is piped through to FOP 
Result res = new SAXResult(fop.getDefaultHandler()); 
//Setup input 
Source src = new StreamSource(new File(xmlPath)); 
//Start the transformation and rendering process 
transformer.transform(src, res); 

nơi xslPath là con đường nơi tập XSLT của tôi được lưu trữ.

Tôi đã xác nhận rằng nó hoạt động khi tôi chỉ có một tệp XSLT, nhưng trong dự án của tôi, tôi đã chia mọi thứ thành nhiều tệp XSLT và nối chúng với thẻ <xsl:import />. Với cấu hình này, tôi nhận được một NullPointerException vì nó không hiểu tất cả các thông tin được lưu trữ trong XSLT bởi vì nó được phân phối trên các tệp khác nhau.

Tôi tự hỏi liệu có cách nào để tải tất cả các tệp này trong biến số Source xsltSrc để tất cả thông tin XSL có sẵn hay không.

CẬP NHẬT

Tôi đã thay đổi mã dựa trên câu trả lời được đưa ra bởi Mads Hansen, nhưng nó vẫn không hoạt động. Tôi phải bao gồm các tệp slt XSLT trong classpath, vì vậy tôi tải tệp XSLT bằng ClassLoader. Tôi đã kiểm tra xem URL có đường dẫn chính xác không khi thực hiện url.toExternalForm(). Đây là đoạn mã mới của tôi:

ClassLoader cl = this.getClass().getClassLoader(); 
String systemID = "resources/xslt/myfile.xslt"; 
InputStream in = cl.getResourceAsStream(systemID); 
URL url = cl.getResource(systemID); 
Source source = new StreamSource(in); 
source.setSystemId(url.toExternalForm()); 
transformer = tFactory.newTransformer(source); 

Tìm và tải myfile.xslt nhưng vẫn không giải quyết được đường dẫn tương đối cho các tệp XSLT khác.

Tôi đang làm gì sai?

Trả lời

10

Khi bạn tải một XSLT như một StreamSource và không đặt SystemID, bộ vi xử lý không biết "ở đâu" XSLT là và không thể giải quyết đường dẫn tương đối.

http://www.onjava.com/pub/a/onjava/excerpt/java_xslt_ch5/index.html?page=5

Bằng cách cung cấp một định danh hệ thống như một tham số đến StreamSource, bạn nói bộ xử lý XSLT nơi để nhìn cho commonFooter.xslt. Nếu không có thông số này, bạn có thể gặp lỗi khi bộ xử lý không thể giải quyết URI này. Việc sửa chữa đơn giản là để gọi các setSystemId() phương pháp như sau:

// construct a Source that reads from an InputStream 
Source mySrc = new StreamSource(anInputStream); 
// specify a system ID (a String) so the 
// Source can resolve relative URLs 
// that are encountered in XSLT stylesheets 
mySrc.setSystemId(aSystemId); 
+0

cảm ơn câu trả lời của bạn, nhưng dường như không giải quyết được vấn đề của bạn, mặc dù câu trả lời của bạn có ý nghĩa. Tôi đã cập nhật câu hỏi của mình với các thay đổi trong mã. – Javi

+0

Bạn có thể cần có đường dẫn tuyệt đối cho SystemID của mình. Trừ khi bạn biết nơi nó sẽ được giải quyết con đường tương đối "từ". Hãy thử chuyển đổi đường dẫn tương đối thành một đường dẫn tuyệt đối với một cái gì đó như: 'String xsltSystemId = new File (systemID) .toURL(). ToExternalForm();' hoặc 'String xsltSystemId = new File (relativePath) .getAbsolutePath();' –

+0

thanks , Tôi đã mặc dù trong đó và tôi đã kiểm tra rằng khi tôi làm url.toExternalForm() nó được một con đường tuyệt đối. Nhưng bây giờ tôi không biết vấn đề ở đâu. – Javi

17

tôi chỉ có nó, một câu trả lời cuối (thử nghiệm trên FOP 1.0) ------

Tất cả bạn cần là để thiết lập một resolver uri cho nhà máy của bạn, như công trình sau đây cho tôi:

TransformerFactory transFact = TransformerFactory.newInstance(); 
StreamSource xsltSource = new StreamSource(xsl); 

// XXX for 'xsl:import' to load other xsls from class path 
transFact.setURIResolver(new ClasspathResourceURIResolver()); 
Templates cachedXSLT = transFact.newTemplates(xsltSource); 
Transformer transformer = cachedXSLT.newTransformer(); 


class ClasspathResourceURIResolver implements URIResolver { 
    @Override 
    public Source resolve(String href, String base) throws TransformerException { 
    return new StreamSource(XXX.getClassLoader().getResourceAsStream(href)); 
    } 
} 

và xsl nhập của tôi (vì vậy 'imported.xsl' nên trong classpath):

<xsl:import href="META-INF/companybusinesscredit/imported.xsl"/> 
+0

Cảm ơn bạn rất nhiều, điều này đã giúp tôi tiết kiệm thời gian. –

2

Tôi đang sử dụng Saxon 9.x và vẫn gặp sự cố khi tôi sử dụng tài liệu trong biểu định kiểu. Biểu định kiểu đã được giải quyết chính xác nhưng các xml được đóng gói cùng với biểu định kiểu trong tệp jar không tải như mong đợi ngay cả với setSystemId. Nó dẫn đến không tìm thấy ngoại lệ.Việc mã tùy chỉnh của người giải quyết dễ dàng hơn với mã bên dưới:

JarfileResolver jarfileResolver = new JarfileResolver(); 
transformer.setURIResolver(jarfileResolver); 


public class JarfileResolver implements URIResolver 
{ 
    public Source resolve(String fileName, String base) throws TransformerException 
    { 
     URL url = getClass().getClassLoader().getResource(fileName); 
     StreamSource jarFileSS = new StreamSource(); 

     try 
     { 
      InputStream jarfileIS = url.openStream(); 
      jarFileSS.setInputStream(jarfileIS); 
     } 
     catch(IOException ioExp) 
     { 
      throw new TransformerException(ioExp); 
     } 
     return jarFileSS; 
    } 
} 
Các vấn đề liên quan