当前位置: 首页 > 知识库问答 >
问题:

将名称空间从java传递到xslt,并使用java的参数作为xslt中的节点

周浩淼
2023-03-14

我有一个xslt文件,可以使用ApacheFop将xml文件转换为pdf。但是我的xslt中没有关于名称空间的所有信息。它依赖于xml。我可以用java分析xml文档,并从xml中获取所有名称空间。但我不知道如何将这个名称空间从java传递到xslt文件,以及下一步如何在

我无法粘贴原始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 param xmlPathPrefix传递,并在中的xslt文件中使用它

<xsl:template match="/$xmlPathPrefix/values">

或者在xsl:apply templatesselect属性中

<fo:table-body>
    <xsl:apply-templates select="$xmlPathPrefix//*[not(contains(name(), 'Content'))]"/>
</fo:table-body>

但我得到以下错误:

类型错误评估($xmlPathPrefix)在xsl:应用模板/@选择在第38行75列的test.xsl: XPTY0019:'/'的第一个操作数的所需项类型是节点();提供的值u"ns0:其他公司/ns0:变化..."是原子价值

如何从java传递xmlPathPrefix并在xslt中使用它?我希望将示例字符串作为xmlPathPrefix传递

"ns0:其他公司/ns0:更改"

第二个问题是我的命名空间,pathPrefix可以不同,但本地名称始终相同,例如:

"ns0:OtherCompany/ns0:Changes"
"ns10:OtherCompany/ns15:Changes"
"companyType:OtherCompany/companyChanges:Changes"

或者更多其他选择。当我有xslt时,我必须在中声明标签

我通过的例子

xmlPathPrefix:"ns10:其他公司/ns15:更改"

和命名空间:ns10和ns15

但我不知道怎样才能做到。


共有1个答案

刘才俊
2023-03-14

您是否使用像Saxon9这样的XSLT2处理器?XSLT代码显示version=“2.0”。如果您正在处理各种名称空间,那么XSLT/XPath 2及更高版本中的一种方法是使用通配符*作为名称空间前缀,例如*:OtherCompany/*:Changes将选择任何名称空间中的这些元素。

要参数化select表达式,您需要使用XSLT 3处理器(如Saxon 9.8或9.9)和所谓的阴影属性(如)\u 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编程接口来设置静态参数

 类似资料:
  • 我得到了这个XML,并且必须从中渲染相当多的内容,并且大多数都工作正常,但我在尝试提取的节点集时被踩了一脚,谁的键与元素的匹配,并且属性是硬编码的字符串(在这种情况下是)。node-set将作为参数传递给模板,并且每个颜色行只能出现一次: 在我的XSLT文件中,我有以下内容(摘录): 问题是,这不会传递节点集,而是传递树片段。是否可以进行与上述操作相同但返回节点集的选择? 编辑: 预期节点集: 我

  • 我有以下XML,我能够根据预期输出进行转换和分组,但当我尝试使用命名空间xmlns时=”http://oracle.com/SGGIMDsEvents“但从未奏效。遵循xml示例输入 XSLT代码-对某些部分进行注释只是为了进行命名空间测试,否则效果很好。这里有一个链接,可以在没有命名空间的情况下运行此代码URL-https://xsltfiddle.liberty-development.net

  • 我有这个xml是架构版本3.0http://www.test.com/Service/v3。我需要将其降级到版本1http://www.test.com/Service/v1.为此,我使用XSL来转换它。 但我得到这样的结果 在我的输出XML中,我得到了这个 为什么将其添加到NS2:消息中? 它不在输入xml中。 我遗漏了一些东西。如果有人能指出这个问题,我将不胜感激。 我希望在输出中创建以下内容

  • 问题内容: 我们已经设置了一些参数来在Jenkins中执行构建(使用简单的“参数化构建”设置)。作业被设置为Maven测试。有没有办法以编程方式将这些参数传递到我们的Java代码中?我们需要基于通过Jenkins设置的参数来执行某些更新功能。 问题答案: 是的,您可以通过Maven执行将Jenkins参数传递给Java代码,如下所示: 请注意, $ JOB_PARAM_1 将捕获Jenkins上设

  • 抱歉,如果我问的是新手问题,但名称空间对我来说真的很费解。 我试图从一个XML/XSLT生成多个SVG文档。 我的样式表: 这样做会产生以下输出: 但我希望能够根据计算的内容指定高度和宽度属性 我尝试将“ ”创建为 http://www.w3.org/2000/svg 这将失败,因为它(xmlspy)不允许我分配xmlns属性。 如果不在根(svg)上指定名称空间,则xmlns将自动添加到根 节点

  • 我写了java代码从. xsd文件中获取元数据,即子节点,并将此元数据作为参数传递给. xsl文件,以便根据. xml文件中的对应名称获取值,最后生成. csv格式的输出 XML文档 **其xsd** XSLT样式表 Java代码 公共静态空main(String args[])抛出异常{ 实际输出 我正在得到。csv输出为 预期输出为