将命名空间从 java 传递到 xslt 并将来自 java 的参数用作 xslt 中的节点
Pass namespaces from java to xslt and use params from java as node in xslt
我有一个 xslt 文件,可以使用 apache-fop 将 xml 文件转换为 pdf。但是我的 xslt 中没有关于名称空间的所有信息。这取决于 xml。我可以分析 java 中的 xml 文档并从 xml 中获取所有命名空间。但我不知道如何将此命名空间从 java 传递到我的 xslt 文件以及接下来如何在 <xsl:stylesheet>
标记中声明它。可能吗?
我无法粘贴我的原始 xslt 和 xml,因为它包含敏感数据,但我准备了示例文件来说明我的问题:
<?xml version="1.0" encoding="UTF-8"?>
<ns0:OtherCompany xmlns:ns8="http://www.company.com/schema/SF/definition/type/test" xmlns:ns0="http://www.company.com/schema/SF/definition/type/a" xmlns:ns7="http://www.company.com/schema/SF/definition/type/b" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ns0:Header>
<ns8:From>2018-01-01</ns8:From>
<ns8:To>2018-12-31</ns8:To>
<ns8:CheckDate>2019-03-28</ns8:CheckDate>
<ns7:Code sysCode="1">Report</ns7:Code>
<ns7:Type>1</ns7:Type>
</ns0:Header>
<ns0:Changes>
<ns7:I>
<ns8:AmountA>1499142.61</ns8:AmountA>
<ns8:AmountB>54979.16</ns8:AmountB>
</ns7:I>
<ns7:II>
<ns8:AmountA>3398983.19</ns8:AmountA>
<ns8:AmountB>1499142.61</ns8:AmountB>
</ns7:II>
<ns7:III>
<ns8:AmountA>3398983.19</ns8:AmountA>
<ns8:AmountB>1499142.61</ns8:AmountB>
</ns7:III>
</ns0:Changes>
</ns0:OtherCompany>
和 xslt:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions"
xmlns:fo="http://www.w3.org/1999/XSL/Format" exclude-result-prefixes="fo" xmlns:ns0="http://www.company.com/schema/SF/definition/type/a" xmlns:ns7="http://www.company.com/schema/SF/definition/type/b">
<xsl:param name="xmlPathPrefix"/>
<xsl:template match="/">
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="simpleA4" page-height="30cm" page-width="26cm" margin-top="2cm" margin-bottom="2cm" margin-left="1cm" margin-right="1cm">
<fo:region-body region-name="xsl-region-body" margin-top=".80in" margin-bottom=".50in"/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="simpleA4">
<fo:flow flow-name="xsl-region-body">
<fo:block font-size="10pt" font-family="Arial">
<fo:table table-layout="fixed" width="100%">
<fo:table-column column-width="12cm" xsl:use-attribute-sets="columnStyle"/>
<fo:table-column column-width="12cm" xsl:use-attribute-sets="columnStyle"/>
<fo:table-header>
<fo:table-row xsl:use-attribute-sets="columnStyle">
<fo:table-cell xsl:use-attribute-sets="centerCellStyle">
<fo:block font-weight="bold">Name</fo:block>
</fo:table-cell>
<fo:table-cell xsl:use-attribute-sets="centerCellStyle">
<fo:block font-weight="bold">Value</fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-header>
<fo:table-body>
<xsl:apply-templates select="$xmlPathPrefix//*[not(contains(name(), 'Content'))]"/>
</fo:table-body>
</fo:table>
</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
<xsl:template match="$xmlPathPrefix//*[not(contains(name(), 'Content'))]">
<fo:table-row xsl:use-attribute-sets="columnStyle">
<fo:table-cell>
<fo:block>
<xsl:value-of select="sf:addSpaces(local-name(), sf:depth-of-node(.))"/>
</fo:block>
</fo:table-cell>
<fo:table-cell xsl:use-attribute-sets="marginColumnStyle">
<fo:block>
<xsl:choose>
<xsl:when test="*">
<xsl:value-of select="''"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="current()"/>
</xsl:otherwise>
</xsl:choose>
</fo:block>
</fo:table-cell>
</fo:table-row>
</xsl:template>
</xsl:stylesheet>
我想从 java 参数 xmlPathPrefix 传递并在 <xsl:template>
匹配属性
的 xslt 文件中使用它
<xsl:template match="/$xmlPathPrefix/values">
或在xsl:apply-templates
select属性中
<fo:table-body>
<xsl:apply-templates select="$xmlPathPrefix//*[not(contains(name(), 'Content'))]"/>
</fo:table-body>
但是我得到以下错误:
Type error evaluating ($xmlPathPrefix) in xsl:apply-templates/@select on line 38 column 75 of test.xsl:
XPTY0019: The required item type of the first operand of '/' is node(); the supplied value
u"ns0:OtherCompany/ns0:Changes..." is an atomic value
如何从 java 传递 xmlPathPrefix 并在我的 xslt 中使用它?我想将示例字符串作为 xmlPathPrefix
"ns0:OtherCompany/ns0:Changes"
第二个问题是我的命名空间,pathPrefix 可以不同,但 local-name 始终相同,示例可以是:
"ns0:OtherCompany/ns0:Changes"
"ns10:OtherCompany/ns15:Changes"
"companyType:OtherCompany/companyChanges:Changes"
或更多其他选项。当我有 xslt 时,我必须在 <xsl:stylesheet>
示例 ns0、ns10、companyType 等中声明标签。如果我不声明它,我会出错。但是我不知道我的 xml 中声明了什么名称空间。我如何将它传递给 xslt?
我通过的例子
xmlPathPrefix: "ns10:OtherCompany/ns15:Changes"
and namespaces for this: ns10 and ns15
但是我不知道怎么到达。
您是否使用像 Saxon 9 这样的 XSLT 2 处理器?您的 XSLT 代码显示 version="2.0"
。如果您正在处理各种命名空间,那么 XSLT/XPath 2 及更高版本中的一种方法是使用通配符 *
作为命名空间前缀,例如*:OtherCompany/*:Changes
将 select 任何名称空间中的那些元素。
要参数化 select
表达式,您需要使用 XSLT 3 处理器,如 Saxon 9.8 或 9.9,以及所谓的影子属性,如 _select
和静态参数:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:param name="prefix" as="xs:string" static="yes" select="'/*:root/*:foo'"/>
<xsl:output indent="yes"/>
<xsl:template match="/">
<xsl:apply-templates _select="{$prefix}/*:bar"/>
</xsl:template>
<xsl:template match="*:bar">
<xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/ej9EGco
我认为您需要使用 Saxon 的 s9api 编程接口来设置静态参数。
我有一个 xslt 文件,可以使用 apache-fop 将 xml 文件转换为 pdf。但是我的 xslt 中没有关于名称空间的所有信息。这取决于 xml。我可以分析 java 中的 xml 文档并从 xml 中获取所有命名空间。但我不知道如何将此命名空间从 java 传递到我的 xslt 文件以及接下来如何在 <xsl:stylesheet>
标记中声明它。可能吗?
我无法粘贴我的原始 xslt 和 xml,因为它包含敏感数据,但我准备了示例文件来说明我的问题:
<?xml version="1.0" encoding="UTF-8"?>
<ns0:OtherCompany xmlns:ns8="http://www.company.com/schema/SF/definition/type/test" xmlns:ns0="http://www.company.com/schema/SF/definition/type/a" xmlns:ns7="http://www.company.com/schema/SF/definition/type/b" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ns0:Header>
<ns8:From>2018-01-01</ns8:From>
<ns8:To>2018-12-31</ns8:To>
<ns8:CheckDate>2019-03-28</ns8:CheckDate>
<ns7:Code sysCode="1">Report</ns7:Code>
<ns7:Type>1</ns7:Type>
</ns0:Header>
<ns0:Changes>
<ns7:I>
<ns8:AmountA>1499142.61</ns8:AmountA>
<ns8:AmountB>54979.16</ns8:AmountB>
</ns7:I>
<ns7:II>
<ns8:AmountA>3398983.19</ns8:AmountA>
<ns8:AmountB>1499142.61</ns8:AmountB>
</ns7:II>
<ns7:III>
<ns8:AmountA>3398983.19</ns8:AmountA>
<ns8:AmountB>1499142.61</ns8:AmountB>
</ns7:III>
</ns0:Changes>
</ns0:OtherCompany>
和 xslt:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions"
xmlns:fo="http://www.w3.org/1999/XSL/Format" exclude-result-prefixes="fo" xmlns:ns0="http://www.company.com/schema/SF/definition/type/a" xmlns:ns7="http://www.company.com/schema/SF/definition/type/b">
<xsl:param name="xmlPathPrefix"/>
<xsl:template match="/">
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="simpleA4" page-height="30cm" page-width="26cm" margin-top="2cm" margin-bottom="2cm" margin-left="1cm" margin-right="1cm">
<fo:region-body region-name="xsl-region-body" margin-top=".80in" margin-bottom=".50in"/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="simpleA4">
<fo:flow flow-name="xsl-region-body">
<fo:block font-size="10pt" font-family="Arial">
<fo:table table-layout="fixed" width="100%">
<fo:table-column column-width="12cm" xsl:use-attribute-sets="columnStyle"/>
<fo:table-column column-width="12cm" xsl:use-attribute-sets="columnStyle"/>
<fo:table-header>
<fo:table-row xsl:use-attribute-sets="columnStyle">
<fo:table-cell xsl:use-attribute-sets="centerCellStyle">
<fo:block font-weight="bold">Name</fo:block>
</fo:table-cell>
<fo:table-cell xsl:use-attribute-sets="centerCellStyle">
<fo:block font-weight="bold">Value</fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-header>
<fo:table-body>
<xsl:apply-templates select="$xmlPathPrefix//*[not(contains(name(), 'Content'))]"/>
</fo:table-body>
</fo:table>
</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
<xsl:template match="$xmlPathPrefix//*[not(contains(name(), 'Content'))]">
<fo:table-row xsl:use-attribute-sets="columnStyle">
<fo:table-cell>
<fo:block>
<xsl:value-of select="sf:addSpaces(local-name(), sf:depth-of-node(.))"/>
</fo:block>
</fo:table-cell>
<fo:table-cell xsl:use-attribute-sets="marginColumnStyle">
<fo:block>
<xsl:choose>
<xsl:when test="*">
<xsl:value-of select="''"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="current()"/>
</xsl:otherwise>
</xsl:choose>
</fo:block>
</fo:table-cell>
</fo:table-row>
</xsl:template>
</xsl:stylesheet>
我想从 java 参数 xmlPathPrefix 传递并在 <xsl:template>
匹配属性
<xsl:template match="/$xmlPathPrefix/values">
或在xsl:apply-templates
select属性中
<fo:table-body>
<xsl:apply-templates select="$xmlPathPrefix//*[not(contains(name(), 'Content'))]"/>
</fo:table-body>
但是我得到以下错误:
Type error evaluating ($xmlPathPrefix) in xsl:apply-templates/@select on line 38 column 75 of test.xsl: XPTY0019: The required item type of the first operand of '/' is node(); the supplied value u"ns0:OtherCompany/ns0:Changes..." is an atomic value
如何从 java 传递 xmlPathPrefix 并在我的 xslt 中使用它?我想将示例字符串作为 xmlPathPrefix
"ns0:OtherCompany/ns0:Changes"
第二个问题是我的命名空间,pathPrefix 可以不同,但 local-name 始终相同,示例可以是:
"ns0:OtherCompany/ns0:Changes"
"ns10:OtherCompany/ns15:Changes"
"companyType:OtherCompany/companyChanges:Changes"
或更多其他选项。当我有 xslt 时,我必须在 <xsl:stylesheet>
示例 ns0、ns10、companyType 等中声明标签。如果我不声明它,我会出错。但是我不知道我的 xml 中声明了什么名称空间。我如何将它传递给 xslt?
我通过的例子
xmlPathPrefix: "ns10:OtherCompany/ns15:Changes"
and namespaces for this: ns10 and ns15
但是我不知道怎么到达。
您是否使用像 Saxon 9 这样的 XSLT 2 处理器?您的 XSLT 代码显示 version="2.0"
。如果您正在处理各种命名空间,那么 XSLT/XPath 2 及更高版本中的一种方法是使用通配符 *
作为命名空间前缀,例如*:OtherCompany/*:Changes
将 select 任何名称空间中的那些元素。
要参数化 select
表达式,您需要使用 XSLT 3 处理器,如 Saxon 9.8 或 9.9,以及所谓的影子属性,如 _select
和静态参数:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:param name="prefix" as="xs:string" static="yes" select="'/*:root/*:foo'"/>
<xsl:output indent="yes"/>
<xsl:template match="/">
<xsl:apply-templates _select="{$prefix}/*:bar"/>
</xsl:template>
<xsl:template match="*:bar">
<xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/ej9EGco
我认为您需要使用 Saxon 的 s9api 编程接口来设置静态参数。