XSLT 文档函数在 Maven POM 上返回空结果

问题描述 投票:0回答:4

您好!

我想通过文档功能从 XSLT 中的不同 Maven POM 中提取一些属性。脚本本身工作正常,但只要项目标签中有 xmlns="http://maven.apache.org/POM/4.0.0",文档函数就会为 POM 返回空结果。如果我删除它,一切都会正常。

知道如何在将 xmlns 属性保留在其所属位置的同时使其工作吗?或者为什么这不适用于该属性?

这是我的 XSLT 的相关部分:

<xsl:template match="abcs">
 <xsl:variable name="artifactCoordinate" select="abc"/>
   <xsl:choose>
        <xsl:when test="document(concat($artifactCoordinate,'-pom.xml'))">
         <abc>
          <ID><xsl:value-of select="$artifactCoordinate"/></ID>
    <xsl:copy-of select="document(concat($artifactCoordinate,'-pom.xml'))/project/properties"/>
   </abc>
         </xsl:when>
            <xsl:otherwise>
       <xsl:message terminate="yes">
           Transformation failed: POM "<xsl:value-of select="concat($artifactCoordinate,'-pom.xml')"/>" doesn't exist. 
       </xsl:message>
      </xsl:otherwise> 

</xsl:choose> 

并且,为了完整起见,带有“bad”属性的 POM 摘录:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- ... -->
<properties>
    <proalpha.version>[5.2a]</proalpha.version>
    <proalpha.openedge.version>[10.1B]</proalpha.openedge.version>
    <proalpha.optimierer.version>[1.1]</proalpha.optimierer.version>
    <proalpha.sonic.version>[7.6.1]</proalpha.sonic.version>
</properties>
 </project>
xslt maven pom.xml
4个回答
11
投票

您的问题是 POM 提取使用默认命名空间。这意味着这些元素虽然没有前缀,但位于“http://maven.apache.org/POM/4.0.0”中——而不是“无命名空间”中。

但是,在这个 XPath 表达式中,在 XSLT 代码中:

document(concat($artifactCoordinate,'-pom.xml'))/project/properties

名称

project
properties
没有前缀。 XPath 始终将无前缀名称视为属于“无命名空间”。因此,找不到此类元素,也不会选择任何节点。

解决方案:将命名空间定义添加到您的

<xsl:stylesheet>
,让我们说:

  xmlns:p="http://maven.apache.org/POM/4.0.0"

然后将引用 POM 节点的任何表达式中的元素名称从

someElement
重写为
p:someElement
。例如:

document(concat($artifactCoordinate,'-pom.xml'))/p:project/p:properties

3
投票

这是一个命名空间问题。源文档中的

xmlns="http://maven.apache.org/POM/4.0.0"
表示所有元素默认放入 XML 文档中的“http://maven.apache.org/POM/4.0.0”命名空间中。

如果您想在 xslt 中获取它们,则需要在 xslt 中声明该名称空间(带或不带要使用的前缀),然后在选择元素时使用该名称空间。

例如,我猜测示例中的模板是为了匹配 POM 中的“abcs”元素,是吗?尝试在 xsl:stylesheet 中添加名称空间声明,例如:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:pom="http://maven.apache.org/POM/4.0.0" version="1.0">

这对 XSL 来说“我想添加 'pom' 作为前缀,用于标识本文档中的 'http://maven.apache.org/POM/4.0.0' 命名空间。”

然后在选择元素或匹配模板时,使用该前缀,例如:

<xsl:template match="pom:abcs">

或者通过将 POM 命名空间声明为默认样式表来尝试不使用前缀,例如:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns="http://maven.apache.org/POM/4.0.0" version="1.0">

1
投票

节点(如果使用 XSLT 2.0+)也可以通过 * 寻址,因为它们位于另一个名称空间中。

    <xsl:copy-of select="document(concat($artifactCoordinate,'-pom.xml'))/*:project/*:properties)"/> 

如果名称空间未知,这可能非常方便或特别有用。在这种情况下,好的副作用是,如果命名空间以这种方式标记,则来自其他命名空间的节点不会获得注释 - 这在我们的情况下是不需要的。


0
投票

您的业务将专注于设计和建造由改造后的集装箱制成的创新、可持续的箱式房屋。这些房屋将优先考虑生态友好的生活、高效的供暖和制冷系统以及可定制的设计,以作为经济适用房或独特的 Airbnb 租赁。目标是提供适合现代需求的时尚、紧凑、节能的生活空间。

© www.soinside.com 2019 - 2024. All rights reserved.