2010-04-29 2 views
5

인사말!XSLT Document 함수는 Maven POM에서 빈 결과를 반환합니다.

문서 기능을 통해 XSLT에서 다른 Maven POM의 일부 속성을 추출하고 싶습니다. 스크립트 자체는 정상적으로 작동하지만 프로젝트 태그에 xmlns = "http://maven.apache.org/POM/4.0.0"이있는 한 문서 함수는 POM에 대해 빈 결과를 반환합니다. 제거하면 모든 것이 잘 작동합니다.

xmlns 속성이 속한 곳에서 떠나는 동안 왜이 기능이 작동하는지, 또는 왜이 기능이 해당 속성에서 작동하지 않는지 생각해보십시오. 완전성에 대한

<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 추출물 :이 네임 스페이스는

<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

좋은 질문 (+1). 문제에 대한 설명과 가장 자주 사용되는 솔루션에 대한 내 대답을 참조하십시오. :) –

답변

10

문제는 POM 추출물이 기본 네임 스페이스을 사용한다는 것입니다. 이것은 접두어가 붙지 않았지만 요소가 "http://maven.apache.org/POM/4.0.0"에 있고 "네임 스페이스가 없습니다"는 것을 의미합니다.

그러나, XSLT 코드에서이 XPath 식에 :

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

이름 projectproperties는 접두어가 있습니다. XPath는 접두어가없는 이름을 "no namespace"에 속하는 것으로 항상 취급합니다. 따라서 이러한 요소는 발견되지 않으며 노드가 선택되지 않습니다.

솔루션 :

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

그런 someElement에서 p:someElement에 POM 노드를 참조하는 어떤 표현의 요소 이름을 다시 작성 : 당신의 <xsl:stylesheet>에 네임 스페이스 정의를 추가, 말할 수 있습니다. 예 :

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

감사합니다. Dimitre -이 작품! 지금이 솔루션은 문서 함수 호출에서 얻은 모든 요소에서 xmlns : pom = "..."을 제공하지만 이전에 대상 문서에 선언을 제공하여이를 제거 할 수있는 방법을 찾기를 희망합니다. – Jan

+0

@Jan : 다음 속성을''에 추가하면됩니다 :'exclude-result-prefixes = "pom"' –

+0

Ah! 멋진 추가 사항입니다. 감사합니다. 나는 또한 나의 특별한 필요에 도움이되는 일반적인 해결책을 발견했다. (내 대답을 보라). – Jan

3

여기

는 관련 내 XSLT 부분을 온다 문제. 원본 문서의 xmlns="http://maven.apache.org/POM/4.0.0"은 기본적으로 모든 요소가 XML 문서의 " http://maven.apache.org/POM/4.0.0"네임 스페이스에 저장된다는 것을 의미합니다.

xslt에서 해당 항목을 가져 오려면 xslt에서 네임 스페이스를 선언하고 (사용하기 위해 접두사가 있거나 없음) 요소를 선택할 때 네임 스페이스를 사용해야합니다.

예를 들어, 예제의 템플릿은 POM의 "abcs"요소와 일치하는 것입니다. 맞습니까? 당신의 XSL에서 네임 스페이스 선언을 추가하려고하면 ". 나는이 문서에서 'http://maven.apache.org/POM/4.0.0'네임 스페이스를 식별하는 접두어로 '치어'을 추가 할"스타일 시트, 예컨대 :

<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로 말한다 요소를 선택하거나 템플릿을 일치시킬 때

그런 다음 그 접두사, 예를 들어, 사용

<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"> 
+0

고마워요! 슬프게도 "글로벌 접근법"은 저에게 효과적이지 않습니다 - 다른 네임 스페이스의 태그도 있기 때문에 분명히 있습니다. 어쩌면 제 질문이 정확하지 않을 수도 있습니다. abcs는 다른 네임 스페이스에 있습니다. 접두사 당 접근 방식은 아래에 제안 된 Dimitre와 같이 저에게 효과적입니다. – Jan

+0

@Matt : XPath로 요소를 선택할 때 기본 네임 스페이스를 원한다면 http://www.w3.org/TR에 설명 된대로 xpath-default-namespace (XSLT 2.0 이상에서 지원)를 사용해야합니다./xslt20/# unprefixed-qnames. 'xmlns = "..."로 기본 네임 스페이스를 설정하면 스타일 시트에서 XML 리터럴의 기본 네임 스페이스 만 구성되므로 XPath 표현식은 영향을받지 않습니다. – markusk

+0

@ markusk 설명해 주셔서 감사합니다. 나는 아직 xpath-default-namespace를 사용하지 않았다. 물론 내 미래에 어느 시점에서 유용 할 것이다! –

1

노드가 (XSLT 2.0 이상을 사용하는 경우) 노드가 다른 네임 스페이스에 있으므로 * 경유 할 수도 있습니다.

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

이것은 네임 스페이스를 알 수없는 경우에만 유용하거나 특히 유용 할 수 있습니다. 이 경우 좋은 측면 효과는 네임 스페이스가이 방법으로 표시되어 다른 네임 스페이스의 노드가 주석을 얻지 못한다는 것인데, 이는 우리의 경우에는 필요하지 않습니다.

+1

@Jan :'* : name' 구문은 XPath 2.0에서만 지원됩니다. –

+0

@Jan : http://www.w3.org/TR/xslt20/#unprefixed-qnames에 설명 된대로 XSLT 2.0 이상을 사용하는 경우'xpath-default-namespace'를 사용할 수 있습니다. – markusk

+0

@Dimitre : 죄송합니다. 세부 정보를 사용하는 것을 잊어 버렸습니다. – Jan