Приветствия!
Я хочу извлечь некоторые свойства из разных Maven POM в XSLT с помощью функции документа. Сам скрипт работает нормально, но функция документа возвращает пустой результат для POM, если у меня есть xmlns = "http://maven.apache.org/POM/4.0.0" в тег проекта. Если удалить, все работает нормально.
Любая идея, как заставить это работать, оставляя атрибут 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>
И, для полноты, извлечение POM с атрибутом "bad":
<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>
3 ответа
Ваша проблема в том, что извлечение 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
<xsl:stylesheet>
следующий атрибут: exclude-result-prefixes="pom"
Это проблема пространства имен. xmlns="http://maven.apache.org/POM/4.0.0"
в исходном документе означает, что все элементы по умолчанию помещаются в "http://maven.apache.org/POM/4.0.0 "в XML-документе.
Если вы хотите заполучить их в своем xslt, вам необходимо объявить это пространство имен в своем xslt (с префиксом или без него), а затем использовать это пространство имен при выборе элементов.
Например, я предполагаю, что шаблон в вашем примере предназначен для соответствия элементу «abcs» в вашем POM, да? Попробуйте добавить объявление пространства имен в свою таблицу стилей xsl:, например:
<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">
xpath-default-namespace
(поддерживается в XSLT 2.0 или новее), как описано в w3.org/TR/xslt20/#unprefixed-qnames. Установка пространства имен по умолчанию с помощью xmlns="..."
только настраивает пространство имен по умолчанию для литералов XML в таблице стилей, выражения XPath не затрагиваются.
К узлам (при использовании XSLT 2.0+) также можно обращаться через *, потому что они находятся в другом пространстве имен.
<xsl:copy-of select="document(concat($artifactCoordinate,'-pom.xml'))/*:project/*:properties)"/>
Это может быть удобно или особенно полезно, если пространство имен неизвестно. В этом случае приятным побочным эффектом является то, что если пространство имен помечено таким образом, узлы из другого пространства имен не получают аннотации, что в нашем случае нежелательно.
*:name
поддерживается только в XPath 2.0.
xpath-default-namespace
, если используете XSLT 2.0 или новее, как описано в w3.org/TR/xslt20/#unprefixed-qnames.
Похожие вопросы
Новые вопросы
xslt
XSLT - это язык преобразования XML, предназначенный для преобразования структурированных документов в другие форматы (например, XML, HTML и простой текст или, в XSLT 3, JSON). Вопросы должны использовать один из тегов xslt-1.0, xslt-2.0 или xslt-3.0 в зависимости от ситуации.