问候!
我想通过文档函数从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>
答案 0 :(得分: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"
然后在引用从someElement
到p:someElement
的POM节点的任何表达式中重写元素名称。例如:
document(concat($artifactCoordinate,'-pom.xml'))/p:project/p:properties
答案 1 :(得分: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">
答案 2 :(得分:1)
Node can(如果使用XSLT 2.0+)也可以通过*来解决,因为它们位于另一个命名空间中。
<xsl:copy-of select="document(concat($artifactCoordinate,'-pom.xml'))/*:project/*:properties)"/>
如果名称空间未知,这可能只是方便或特别有用。在这种情况下,好的副作用是,如果命名空间以这种方式标记,则来自另一个命名空间的节点不会得到注释 - 在我们的情况下不需要注释。