gpt4 book ai didi

java - 如何使用 Javax.xml.transformer API 将 XML 文档传递给 XSL 文件?

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:23:48 24 4
gpt4 key购买 nike

我正在使用 javax.xml.transform API 进行 XSL 转换。 API 仅允许一个 XML 文档作为输入来应用如下转换。

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
StringWriter stringWriter = new StringWriter();
File xml = new File("C:\\abc");
File xsl = new File("C:\\def.xsl");
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
document = builder.parse(xml);
TransformerFactory transformerFactory =
TransformerFactory.newInstance();
StreamSource style = new StreamSource(xsl);
Transformer transformer = transformerFactory.newTransformer(style);
DOMSource source = new DOMSource(document);

此外,可以像下面这样传递简单的字符串参数,没有任何问题,如下所示:

transformer.setParameter("mode", "CREATE");

但是,我想将 XML 文档作为参数传递给 XSL 文件。我按照其中一个 SO 页面上的建议尝试了以下代码,如下所示:

DocumentBuilder builder = factory.newDocumentBuilder();
final Document documentFile = builder.parse(xml2);
Map<String, Document> docs = new HashMap<String, Document>();
docs.put("lookup", documentFile);
transformer.setURIResolver(new DocumentURIResolver(docs));

我设置了 XML 中的标签以接收如下值:

<xsl:variable name="lookup" select="('documentFile')/>  . 

但它对我不起作用。任何人都可以通过 javax.xml.transform API 以正确的方式帮助我将多个 XML 文档传递到任何 XSL 文件吗?

更新

问题仍然存在,谁能告诉我如何将 XML 对象作为参数传递到 XSLT 2.0 样式表中。我尝试了不同的方法,但仍然没有运气。我需要知道通过 JAVA xsl 转换 API 的出路。

最佳答案

我认为您的问题出在 XSLT 中。改变

<xsl:variable name="lookup" select="('documentFile')/>  . 

<xsl:variable name="lookup" select="document('lookup')/>

这将导致转换器使您的文档的 DOM 可在变量 lookup 中访问。关键 lookup 来自 docs.put("lookup", documentFile);

通过 URIResolver 将多个 XML 源动态传递到 XSL 转换。

完整工作示例:

存在三个XML文件:repo.xmlbooks.xmlarticles.xmlrepo.xml 包含有关书籍和文章的状态信息。 articles.xmlbooks.xml 文件包含有关每个项目的标题信息。目标是打印所有书籍和文章的状态信息以及标题信息。所有文件中的条目都通过 id 键连接。

github 找到完整的例子或复制/粘贴下面的列表。

repo.xml

<repository>
<book>
<id>1</id>
<status>available</status>
</book>
<book>
<id>2</id>
<status>lost</status>
</book>
<article>
<id>1</id>
<status>in transit</status>
</article>
</repository>

书籍.xml

<books>
<book id="1">
<title>Book One</title>
</book>
<book id="2">
<title>Book Two</title>
</book>
<book id="3">
<title>Book Three</title>
</book>
</books>

文章.xml

<articles>
<article id="1">
<title>Article One</title>
</article>
<article id="2">
<title>Article Two</title>
</article>
<article id="3">
<title>Article Three</title>
</article>
</articles>

加入.xsl

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">


<xsl:output method="xml" encoding="UTF-8" indent="yes" />

<xsl:template match="/">
<titleStatusJoin>
<xsl:for-each select="//book">
<xsl:variable name="myId" select="id" />
<book>
<status>
<xsl:value-of select="status" />
</status>
<title>
<xsl:for-each select="document('bookFile')//book">
<xsl:variable name="bookId" select="@id" />
<xsl:choose>
<xsl:when test="$myId = $bookId">
<xsl:value-of select="title" />
</xsl:when>
</xsl:choose>
</xsl:for-each>
</title>
</book>
</xsl:for-each>
<xsl:for-each select="//article">
<xsl:variable name="myId" select="id" />
<article>
<status>
<xsl:value-of select="status" />
</status>
<title>
<xsl:for-each select="document('articleFile')//article">
<xsl:variable name="bookId" select="@id" />
<xsl:choose>
<xsl:when test="$myId = $bookId">
<xsl:value-of select="title" />
</xsl:when>
</xsl:choose>
</xsl:for-each>
</title>
</article>
</xsl:for-each>

</titleStatusJoin>
</xsl:template>
</xsl:stylesheet>

使用此 Java 代码...

@Test
public void useMultipleXmlSourcesInOneXsl3() {
InputStream xml = Thread.currentThread().getContextClassLoader().getResourceAsStream("stack54335576/repo.xml");
InputStream xsl = Thread.currentThread().getContextClassLoader().getResourceAsStream("stack54335576/join3.xsl");
InputStream booksXml = Thread.currentThread().getContextClassLoader()
.getResourceAsStream("stack54335576/books.xml");
InputStream articlesXml = Thread.currentThread().getContextClassLoader()
.getResourceAsStream("stack54335576/articles.xml");
Document booksDom = readXml(booksXml);
Document articlesDom = readXml(articlesXml);
Map<String, Document> parameters = new HashMap<>();
parameters.put("bookFile", booksDom);
parameters.put("articleFile", articlesDom);
xslt(xml, xsl, parameters);
}

public final void xslt(InputStream xml, InputStream xsl, Map<String, Document> parameters) {
try {
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer(new StreamSource(xsl));
transformer.setURIResolver((href, base) -> new DOMSource(parameters.get(href)));
transformer.transform(new StreamSource(xml), new StreamResult(System.out));
} catch (Exception e) {
throw new RuntimeException(e);
}
}

private Document readXml(InputStream xmlin) {
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
return db.parse(xmlin);
} catch (Exception e) {
throw new RuntimeException(e);
}
}

...产生这个输出

<?xml version="1.0" encoding="UTF-8"?>
<titleStatusJoin>
<book>
<status>available</status>
<title>Book One</title>
</book>
<book>
<status>lost</status>
<title>Book Two</title>
</book>
<article>
<status>in transit</status>
<title>Article One</title>
</article>
</titleStatusJoin>

关于java - 如何使用 Javax.xml.transformer API 将 XML 文档传递给 XSL 文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54335576/

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