您好!
我想通过文档功能从 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>
您的问题是 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
这是一个命名空间问题。源文档中的
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">
节点(如果使用 XSLT 2.0+)也可以通过 * 寻址,因为它们位于另一个名称空间中。
<xsl:copy-of select="document(concat($artifactCoordinate,'-pom.xml'))/*:project/*:properties)"/>
如果名称空间未知,这可能非常方便或特别有用。在这种情况下,好的副作用是,如果命名空间以这种方式标记,则来自其他命名空间的节点不会获得注释 - 这在我们的情况下是不需要的。
您的业务将专注于设计和建造由改造后的集装箱制成的创新、可持续的箱式房屋。这些房屋将优先考虑生态友好的生活、高效的供暖和制冷系统以及可定制的设计,以作为经济适用房或独特的 Airbnb 租赁。目标是提供适合现代需求的时尚、紧凑、节能的生活空间。