gpt4 book ai didi

xslt - 当命名空间是动态的时,如何在 XSLT 文件中提及命名空间?

转载 作者:行者123 更新时间:2023-12-04 16:51:29 24 4
gpt4 key购买 nike

我需要将 XML 数据存储在 DB 中,然后从 DB 检索 xml 并转换为 PDF。为此,我将 XSLT 与 Apache FOP 一起使用。下面的代码对 XML 文件中的当前命名空间工作正常(我已将命名空间从 Books.xml 文件复制并粘贴到 Books.xsl 。问题是每当 WebService 的 WebService6x7919 xml 文件被更改,然后我的 Books.xsl 文件与旧命名空间在使用 Apache FOP 生成 PDF 时出现异常。

注意: 如果我根据 XML 文件中的新命名空间更新我的 Books.xsl 文件命名空间,PDF 生成适用于新的 XML 内容,但不适用于旧的 Books.xml 内容。

示例: Webservice 更新前 Books.xml 中的旧命名空间如下

<Book xmlns="http://book.com/one/1.1/" xmlns:ns2="http://test2.com/one/1.1/" xmlns:ns3="http://test3.com/one/1.1/" >

并假设 XML 文件中的新命名空间如下
<Book xmlns="http://book.com/one/1.2/" xmlns:ns2="http://test2.com/one/1.2/" xmlns:ns3="http://test3.com/one/1.2/" >

这是我的 XML 内容( BOOK.xml )
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Book xmlns="http://book.com/one/1.2/" xmlns:ns2="http://test2.com/one/1.2/" xmlns:ns3="http://test3.com/one/1.2/" >
<Title>Java</Title>
<ISBN>123</ISBN>
<Author>Test</Author>
<BookImage>
<ns2:ImageName>images1.jpeg</ns2:ImageName>
<ns2:ImageContent>/aN2r9pT8HwKXpmvvmt2ifpz5xvmt2ifpz5xukZHBb9Wn4FL0xwW/VpD=</ns2:ImageContent>
</BookImage>
<BookImage>
<ns2:ImageName>images2.jpeg</ns2:ImageName>
<ns2:ImageContent>/aN2r9pT8HwKXpmvvmt2ifpz5xvmt2ifpz5xukZHBb9Wn4FL0xwW/VpD=</ns2:ImageContent>
</BookImage>
</Book>

以下是我的 xsl 内容( Books.xsl )
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:b="http://book.com/one/1.1/" xmlns:ns2="http://test2.com/one/1.1/" xmlns:ns3="http://test3.com/one/1.1/">

<xsl:template match="b:Book">

<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="ex"
page-height="29.7cm" page-width="21cm" margin-top="2cm"
margin-bottom="2cm" margin-left="2cm" margin-right="2cm">
<fo:region-body />
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="ex">
<fo:flow flow-name="xsl-region-body">

<fo:block space-after="15mm">

</fo:block>
<fo:block font-size="16pt" font-weight="bold" space-after="5mm">
Book Details
</fo:block>

<fo:block font-size="10pt">
<fo:table table-layout="fixed" width="100%"
border-collapse="collapse" border="solid 1px black">

<fo:table-body>
<fo:table-row>
<fo:table-cell border="solid 1px black" padding="1mm">
<fo:block font-weight="bold">Title :</fo:block>
</fo:table-cell>
<fo:table-cell padding="1mm" border="solid 1px black">
<fo:block>
<xsl:value-of select="b:Title" />
</fo:block>
</fo:table-cell>
</fo:table-row>

<fo:table-row>
<fo:table-cell border="solid 1px black" padding="1mm">
<fo:block font-weight="bold">ISBN :
</fo:block>
</fo:table-cell>
<fo:table-cell padding="1mm" border="solid 1px black">
<fo:block>
<xsl:value-of select="b:ISBN" />
</fo:block>
</fo:table-cell>
</fo:table-row>

<fo:table-row>
<fo:table-cell border="solid 1px black" padding="1mm">
<fo:block font-weight="bold">Author :</fo:block>
</fo:table-cell>
<fo:table-cell padding="1mm" border="solid 1px black">
<fo:block>
<xsl:value-of select="b:Author" />
</fo:block>
</fo:table-cell>
</fo:table-row>

<fo:table-row>
<fo:table-cell border="solid 1px black" padding="1mm">
<fo:block font-weight="bold">Image Names :</fo:block>
</fo:table-cell>
<fo:table-cell padding="1mm" border="solid 1px black">
<fo:block>
<xsl:for-each select="b:BookImage">
<xsl:value-of select="ns2:ImageName"/>
<xsl:text>&#160;</xsl:text>
</xsl:for-each>
</fo:block>
</fo:table-cell>
</fo:table-row>


</fo:table-body>
</fo:table>
</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
</xsl:stylesheet>

和java代码如下
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;

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.fop.apps.FOUserAgent;
import org.apache.fop.apps.Fop;
import org.apache.fop.apps.FopFactory;
import org.apache.fop.apps.MimeConstants;

/**
* This class demonstrates the conversion of an XML file to PDF using
* JAXP (XSLT) and FOP (XSL-FO).
*/
public class ExampleXML2PDF {

/**
* Main method.
* @param args command-line arguments
*/
public static void main(String[] args) {
ExampleXML2PDF exampleXML2PDF = new ExampleXML2PDF();
exampleXML2PDF.xmlToPDF();
}


public void xmlToPDF(){

try {
System.out.println("FOP ExampleXML2PDF\n");
System.out.println("Preparing...");
System.out.println("Transforming...");

// configure fopFactory as desired
final FopFactory fopFactory = FopFactory.newInstance();

FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
// configure foUserAgent as desired
InputStream xslInputStream = getClass().getResourceAsStream("/resources/Book.xsl");

InputStream xmlInputStream = getClass().getResourceAsStream("/resources/Book.xml");

// Setup output
OutputStream out = new java.io.FileOutputStream(new File("bin/resources/BookXML2PDF.pdf"));
out = new java.io.BufferedOutputStream(out);

try {
// Construct fop with desired output format
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out);

// Setup XSLT
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer(new StreamSource(xslInputStream));

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

// 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!");
} catch (Exception e) {
e.printStackTrace(System.err);
System.exit(-1);
}

}

}

任何帮助将提前表示赞赏。

谢谢,
饶波特拉

最佳答案

如果您事先知道可能的命名空间集合是什么,并且它是一个小集合,您可以这样做:

<xsl:template match="b:Book | ns1:Book | ns2:Book">
...
<xsl:value-of select="b:Title | ns1:Title | ns2:Title" />

如果您必须多次这样做,那会变得有点困惑,但它的优点是(?)它不会接受来自任何命名空间的元素(例如,没有命名空间的元素)。根据您的情况,这可能不是优势。

如果您事先不知道所有可能的命名空间是什么,您可以使用这个更通用的解决方案,它完全忽略命名空间:
<xsl:template match="*[local-name() = 'Book']">
...
<xsl:value-of select="*[local-name() = 'Title']" />

关于xslt - 当命名空间是动态的时,如何在 XSLT 文件中提及命名空间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16963316/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com