简体   繁体   English

fo:region-body "xsl-region-body" 的边框和填充应该是 '0' 如果启用宽松验证,则允许使用非标准值

[英]Border and padding for fo:region-body "xsl-region-body" should be '0' non-standard values are allowed if relaxed validation is enabled

Hi I am using fop to generate a PDF from XML file您好,我正在使用 fop 从 XML 文件生成一个 PDF

Java 11 version Spring boot starter 2.5.2 Java 11 版本 Spring boot starter 2.5.2

org.apache.xmlgraphics ( fop) version 2.7 org.apache.xmlgraphics (fop) 版本 2.7

I am getting this error我收到这个错误

org.apache.fop.fo.ValidationException: Border and padding for fo:region-body "xsl-region-body" should be '0' (See 6.4.14 in XSL 1.1); org.apache.fop.fo.ValidationException:fo:region-body“xsl-region-body”的边框和填充应为“0”(参见 XSL 1.1 中的 6.4.14); non-standard values are allowed if relaxed validation is enabled.如果启用宽松验证,则允许使用非标准值。 (No context info available) (没有可用的上下文信息)

Please help请帮忙

` `

Starter.java启动器.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 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 file 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 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>`

You can try to set the values to zero on fo:region-body element in your XSL-FO document.您可以尝试将 XSL-FO 文档中的 fo:region-body 元素的值设置为零。 You can also try to enable relaxed validation by setting the "fop.xsl.extension.config" Java system property to "fop.extensions.xsl-fo-extensions.xml" before running FOP.您还可以尝试通过在运行 FOP 之前将“fop.xsl.extension.config”Java 系统属性设置为“fop.extensions.xsl-fo-extensions.xml”来启用宽松验证。

Copy code复制代码

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

This will allow the non-standard values to be used.这将允许使用非标准值。 Please note that enabling relaxed validation may cause other errors and it is not recommended to use it in production.请注意,启用宽松验证可能会导致其他错误,不建议在生产中使用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM