Spring Boot fo:region-body“xsl-region-body”的边框和填充应为'0'如果启用了宽松验证,则允许使用非标准值

xvw2m8pv  于 2023-01-26  发布在  Spring
关注(0)|答案(1)|浏览(123)

嗨,我正在使用fop从XML文件生成PDF
Java 11版本Spring引导启动程序2.5.2
组织。Apache。可扩展标记图形(fop)版本2.7
我收到此错误
org.apache.fop.fo.ValidationException:fo:region-body "xsl-region-body"的边框和填充应为"0"(请参见XSL 1.1中的6.4.14);如果启用了宽松验证,则允许使用非标准值。(没有可用的上下文信息)
请帮帮忙
'
Starter.java

package pack;
import java.io.File;import java.io.OutputStream;import java.net.URI;
import javax.xml.transform.Result;import javax.xml.transform.Source;import javax.xml.transform.Transformer;import javax.xml.transform.TransformerFactory;import javax.xml.transform.sax.SAXResult;import javax.xml.transform.stream.StreamSource;
import org.apache.avalon.framework.configuration.Configuration;import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;import org.apache.fop.apps.FOUserAgent;import org.apache.fop.apps.Fop;import org.apache.fop.apps.FopFactory;import org.apache.fop.apps.FopFactoryBuilder;import org.apache.fop.apps.MimeConstants;import org.apache.fop.events.Event;import org.apache.fop.events.EventListener;import org.apache.fop.events.model.EventSeverity;
public class Start {
public static void main(String[] args) throws Exception {

    System.out.println("FOP ExampleXML2PDF");

    // Setup input and output files
    File xmlfile = new File("src/main/resources/article.xml");
    File xsltfile = new File("src/main/resources/article2fo.xsl");
    File pdffile = new File("article.pdf");
    System.out.println("Input: XML (" + xmlfile + ")");
    System.out.println("Stylesheet: " + xsltfile);
    System.out.println("Output: PDF (" + pdffile + ")");

    System.out.println("Transforming...");

    // NOTE: reuse fopFactory
//        FopFactory fopFactory = getFopFactoryConfiguredFromClasspath("fop.xconf.xml");//        FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI());//        FOUserAgent foUserAgent = fopFactory.newFOUserAgent();//        FopFactory fopFactory = getFopFactoryConfiguredFromFileSystem("fop.xconf.xml");//test by uday startFopFactory fopFactory = getFopFactoryConfiguredFromClasspath("fop.xconf.xml");FOUserAgent userAgent = fopFactory.newFOUserAgent();userAgent.getEventBroadcaster().addEventListener(getInvalidPropertyEventListener());//test by uday end// with userAgent you can further configure some things:// https://xmlgraphics.apache.org/fop/2.2/embedding.html#user-agent//FOUserAgent foUserAgent = fopFactory.newFOUserAgent();// configure foUserAgent as desired
// Setup output
    OutputStream out = new java.io.FileOutputStream(pdffile);
    out = new java.io.BufferedOutputStream(out);

    try {
        // Construct fop with desired output format
//            Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out);Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent,out);
// Setup XSLT
        TransformerFactory factory = TransformerFactory.newInstance();
        Transformer transformer = factory.newTransformer(new StreamSource(xsltfile));

        // Set the value of a <param> in the stylesheet
        transformer.setParameter("versionParam", "2.0");

        // Setup input for XSLT transformation
        Source src = new StreamSource(xmlfile);

        // Resulting SAX events (the generated FO) must be piped through to FOP
        Result res = new SAXResult(fop.getDefaultHandler());

        // Start XSLT transformation and FOP processing
        transformer.transform(src, res);
    } finally {
        out.close();
    }

    System.out.println("Success!");

}

private static EventListener getInvalidPropertyEventListener() {
    Start.InvalidPropertyEventListener lsn = new Start.InvalidPropertyEventListener();
    return lsn;
}

private static class InvalidPropertyEventListener implements EventListener {

    /**
     * Continues processing even if an <code>invalidProperty</code> runtimeException was thrown
     * during FO to PDF transformation.
     * <p>
     * Descends the event's severity level to WARN to avoid the exception throwing.
     *
     * @param event The event to be processed.
     */
    @Override
    public void processEvent(Event event) {
        if ("org.apache.fop.fo.FOValidationEventProducer.invalidProperty".equals(event.getEventID())) {
            event.setSeverity(EventSeverity.WARN);
        }
    }
    
}

/**
 * The fop configuration and referenced resources (ttf font) are loaded
 * from the file system
 * 
 */
private static FopFactory getFopFactoryConfiguredFromFileSystem(String configFileName) throws Exception {
    FopFactory fopFactory = FopFactory.newInstance(new File("src/main/resources/" + configFileName));
    return fopFactory;
}

/**
 * The fop configuration and referenced resources (ttf font) are loaded
 * from the classpath
 * 
 */
private static FopFactory getFopFactoryConfiguredFromClasspath(String configFileName) throws Exception {
    
    URI baseUri = URI.create("base_uri_is_meaningless_in_this_case");
    // System.out.println("uri: " + uri);
    
    // create a builder with a ResourceResolver which reads from the classpath. 
    // The resourceResolver will be called for loading the resources referenced 
    // in the configuration (for example a ttf font)
    FopFactoryBuilder builder = new FopFactoryBuilder(baseUri, new ClasspathResolverURIAdapter());

    // create a configuration which is based on a file read from the classpath
    DefaultConfigurationBuilder cfgBuilder = new DefaultConfigurationBuilder();
    Configuration cfg = cfgBuilder.build(Start.class.getResourceAsStream("/" + configFileName));

    // sets the configuration
    builder.setConfiguration(cfg);

    FopFactory fopFactory = builder.build();
    return fopFactory;
}
}

ClasspathResolverURIAdapter.java

`package pack;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;

import org.apache.fop.apps.io.ResourceResolverFactory;
import org.apache.fop.events.Event;
import org.apache.fop.events.EventListener;
import org.apache.fop.events.model.EventSeverity;
import org.apache.xmlgraphics.io.Resource;
import org.apache.xmlgraphics.io.ResourceResolver;

/**
 * ResourceResolver which loads resources with "classpath:" prefix from the
 * classpath
 * 
 * Based on this:
 * 
 * https://stackoverflow.com/questions/41661997/set-fopfactorybuilder-baseuri-to-jar-classpath
 * 
 */
public class ClasspathResolverURIAdapter implements ResourceResolver {

    private final ResourceResolver wrapped;

    public ClasspathResolverURIAdapter() {
        this.wrapped = ResourceResolverFactory.createDefaultResourceResolver();
    }

    
    @Override
    public Resource getResource(URI uri) throws IOException {
        System.out.println("getresource called, uri is: " + uri + ", path is: " + uri.getSchemeSpecificPart());
        if (uri.getScheme().equals("classpath")) {
            InputStream is = Start.class.getResourceAsStream(uri.getSchemeSpecificPart());
            System.out.println("is: " + is);
            return new Resource(is);
        } else {
            return wrapped.getResource(uri);
        }
    }

    @Override
    public OutputStream getOutputStream(URI uri) throws IOException {
        if (uri.getScheme().equals("classpath")) {
            throw new RuntimeException("This is a read only ResourceResolver. You can not use it's outputstream");
        } else {
            return wrapped.getOutputStream(uri);
        }
    }

}`

article2fo.xsl文件

`<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:fo="http://www.w3.org/1999/XSL/Format"
      xmlns:lgcy="urn:tarhely.gov.hu:1.0:legacy"
      >
  <xsl:output method="xml" indent="yes"/>
  
  <xsl:template match="header1">
            <fo:block font-size="24pt">
                <xsl:apply-templates select="node()"/>
          </fo:block>
  </xsl:template>
  
  <xsl:template match="para">
            <fo:block font-size="12pt">
                <xsl:apply-templates select="node()"/>
          </fo:block>
  </xsl:template>

  <xsl:template match="/">
  <!-- 
    <fo:root>
     -->
    <fo:root font-family="FreeSans">
    
      <fo:layout-master-set>
        <fo:simple-page-master master-name="A4-portrait"
              page-height="29.7cm" page-width="21.0cm" margin="2cm">
          <fo:region-body margin-bottom="0.5in" border="solid"/>
        </fo:simple-page-master>
      </fo:layout-master-set>
      <fo:page-sequence master-reference="A4-portrait">
        <fo:flow flow-name="xsl-region-body">
        
          <xsl:copy>
            <xsl:apply-templates select="node()"/>
          </xsl:copy>
          
        </fo:flow>
      </fo:page-sequence>
    </fo:root>
  </xsl:template>
</xsl:stylesheet>`

fop.xconf.xml

`<?xml version="1.0"?>
<!-- $Id: fop.xconf 1616312 2014-08-06 19:19:31Z gadams $ -->

<!--
This is a shortened example configuration file for FOP.
Based on the fop.xconf from the distribution zip.
-->

<!-- NOTE: This is the version of the configuration -->
<fop version="1.0">

  <!-- Base URL for resolving relative URLs -->
  <base>.</base>
  
  <!-- Source resolution in dpi (dots/pixels per inch) for determining the size of pixels in SVG and bitmap images, default: 72dpi -->
  <source-resolution>72</source-resolution>
  <!-- Target resolution in dpi (dots/pixels per inch) for specifying the target resolution for generated bitmaps, default: 72dpi -->
  <target-resolution>72</target-resolution>
  
  <!-- Default page-height and page-width, in case value is specified as auto -->
  <default-page-settings height="11.00in" width="8.50in"/>
  
  <!-- Information for specific renderers -->
  <!-- Uses renderer mime type for renderers -->
  <renderers>
    <renderer mime="application/pdf">
      <filterList>
        <!-- provides compression using zlib flate (default is on) -->
        <value>flate</value>
  
        <!-- encodes binary data into printable ascii characters (default off)
             This provides about a 4:5 expansion of data size -->
        <!-- <value>ascii-85</value> -->
  
        <!-- encodes binary data with hex representation (default off)
             This filter is not recommended as it doubles the data size -->
        <!-- <value>ascii-hex</value> -->
      </filterList>

      <fonts>
        <!-- embedded fonts -->
        <!--
        This information must exactly match the font specified
        in the fo file. Otherwise it will use a default font.

        For example,
        <fo:inline font-family="Arial" font-weight="bold" font-style="normal">
            Arial-normal-normal font
        </fo:inline>
        for the font triplet specified by:
        <font-triplet name="Arial" style="normal" weight="bold"/>

        If you do not want to embed the font in the pdf document
        then do not include the "embed-url" attribute.
        The font will be needed where the document is viewed
        for it to be displayed properly.

        possible styles: normal | italic | oblique | backslant
        possible weights: normal | bold | 100 | 200 | 300 | 400
                          | 500 | 600 | 700 | 800 | 900
        (normal = 400, bold = 700)
        -->

        <!--
        FreeSans.ttf is from Xubuntu's /usr/share/fonts/truetype/freefont folder
        -->
        <!-- use this for classpath based configuration
        <font kerning="yes" embed-url="classpath:/FreeSans.ttf">
         -->
        <!-- use this for file system based configuration 
        <font kerning="yes" embed-url="FreeSans.ttf">
         -->
         <font kerning="yes" embed-url="classpath:/FreeSans.ttf">
          <font-triplet name="FreeSans" style="normal" weight="normal"/>
        </font>

        <!-- auto-detect fonts -->
        <!--
        <auto-detect/>
        -->

      </fonts>

      <!-- This option lets you specify additional options on an XML handler -->
      <!--xml-handler namespace="http://www.w3.org/2000/svg">
        <stroke-text>false</stroke-text>
      </xml-handler-->

    </renderer>

  </renderers>

</fop>`
e4eetjau

e4eetjau1#

您可以尝试将XSL-FO文档中的fo:region-body元素的值设置为零,也可以尝试在运行FOP之前通过将"fop.xsl.extensions.config" Java系统属性设置为"fop.extensions.xsl-fo-extensions.xml"来启用宽松验证。
复制代码

System.setProperty("fop.xsl.extension.config", "fop.extensions.xsl-fo-extensions.xml");

这将允许使用非标准值。请注意,启用宽松验证可能会导致其他错误,因此不建议在生产中使用。

相关问题