Функция XSLT Document возвращает пустой результат в Maven POM - PullRequest
6 голосов
/ 29 апреля 2010

Привет!

Я хочу извлечь некоторые свойства из разных POM Maven в 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 ]

11 голосов
/ 29 апреля 2010

Ваша проблема в том, что экстракт POM использует пространство имен по умолчанию . Это означает, что элементы, хотя и без префикса, находятся в «http://maven.apache.org/POM/4.0.0"», а не в «no namespace».

Однако в этом выражении 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 голосов
/ 29 апреля 2010

Это проблема пространства имен. 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">
1 голос
/ 30 апреля 2010

Узел (при использовании XSLT 2.0+) также может быть адресован через *, поскольку он находится в другом пространстве имен.

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

Это может быть просто удобно или особенно полезно, если пространство имен неизвестно. В этом случае приятным побочным эффектом является то, что если пространство имен помечено таким образом, узлы из другого пространства имен не получают аннотации - что в нашем случае нежелательно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...