2010-04-29 38 views
5

Chúc mừng!Chức năng tài liệu XSLT trả về kết quả trống trên Maven POM

Tôi muốn trích xuất một số thuộc tính từ các POM Maven khác nhau trong XSLT thông qua hàm tài liệu. Bản thân kịch bản hoạt động tốt nhưng hàm tài liệu trả về một kết quả trống cho POM miễn là tôi có số xmlns = "http://maven.apache.org/POM/4.0.0" trong thẻ dự án. Nếu tôi gỡ bỏ nó, mọi thứ đều hoạt động tốt.

Bất kỳ ý tưởng nào về cách thực hiện tác vụ này trong khi rời khỏi thuộc tính xmlns nơi thuộc tính hoặc lý do tại sao điều này không hoạt động với thuộc tính tại chỗ?

Ở đây có phần liên quan của XSLT tôi:

<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> 

Và, cho đầy đủ, chiết xuất POM với "xấu" thuộc tính:

<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

Câu hỏi hay (+1). Xem câu trả lời của tôi cho một lời giải thích của vấn đề và cho các giải pháp thường được sử dụng nhất. :) –

Trả lời

10

Vấn đề của bạn là trích xuất POM sử dụng không gian tên mặc định. Điều này có nghĩa là các phần tử, mặc dù không được cố định, nằm trong "http://maven.apache.org/POM/4.0.0" - không nằm trong "không có không gian tên".

Tuy nhiên, trong biểu thức XPath này, trong các mã XSLT:

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

tên projectproperties là không tiền tố. XPath luôn xử lý các tên không được sửa lại là thuộc về "không có không gian tên". Do đó, không tìm thấy thành phần nào và không có nút nào được chọn.

Giải pháp: Thêm một định nghĩa namespace để <xsl:stylesheet> của bạn, cho phép nói:

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

Sau đó viết lại tên phần tử trong bất kỳ biểu thức tham khảo hạch POM từ someElement để p:someElement. Ví dụ:

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

Cảm ơn Dimitre - công trình này! Ngay bây giờ, giải pháp này cho tôi xmlns: pom = "..." trong mọi phần tử mà tôi nhận được từ cuộc gọi hàm tài liệu nhưng tôi hy vọng tìm được cách để loại bỏ điều đó, có lẽ bằng cách cung cấp khai báo trong tài liệu đích trước. – Jan

+0

@Jan: Chỉ cần thêm vào thuộc tính sau: 'exclude-result-prefixes =" pom "' –

+0

Ah! Đó là một bổ sung tốt đẹp - cảm ơn bạn. Tôi cũng tìm thấy một giải pháp chung có ích cho nhu cầu đặc biệt của tôi (xem câu trả lời của tôi). – Jan

3

Đây là một không gian tên vấn đề. xmlns="http://maven.apache.org/POM/4.0.0" trong tài liệu nguồn có nghĩa là tất cả các phần tử theo mặc định được đưa vào không gian tên "http://maven.apache.org/POM/4.0.0" trong tài liệu XML.

Nếu bạn muốn giữ chúng trong xslt, bạn cần khai báo không gian tên đó trong xslt của bạn (có hoặc không có tiền tố để sử dụng) và sau đó sử dụng không gian tên đó khi chọn các phần tử của bạn.

Ví dụ: tôi đoán rằng mẫu trong ví dụ của bạn có nghĩa là khớp với phần tử "abcs" trong POM của bạn, phải không? Hãy thử thêm một tuyên bố namespace trong xsl của bạn: "Tôi muốn thêm 'pom' như một tiền tố xác định 'http://maven.apache.org/POM/4.0.0' namespace trong tài liệu này" stylesheet, ví dụ .:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:pom="http://maven.apache.org/POM/4.0.0" version="1.0"> 

Đó nói với XSL

Sau đó, khi lựa chọn các yếu tố hoặc phù hợp với mẫu, sử dụng tiền tố, ví dụ:

<xsl:template match="pom:abcs"> 

Hoặc thử nó mà không có các tiền tố bằng cách tuyên bố stylesheet của bạn với không gian tên POM như mặc định, một cái gì đó như:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns="http://maven.apache.org/POM/4.0.0" version="1.0"> 
+0

Cảm ơn bạn! Đáng buồn thay, "cách tiếp cận toàn cầu" không hiệu quả đối với tôi - rõ ràng là vì tôi cũng có các thẻ từ các không gian tên khác. Có lẽ câu hỏi của tôi không đủ chính xác - abcs ở trong một không gian tên khác. Tuy nhiên, phương pháp tiếp cận theo từng tiền tố hoạt động cho tôi, như Dimitre được đề xuất bên dưới. – Jan

+0

@Matt: Nếu bạn muốn có một không gian tên mặc định khi chọn các phần tử với XPath, bạn cần sử dụng 'xpath-default-namespace' (được hỗ trợ trong XSLT 2.0 hoặc mới hơn), như được mô tả trong http://www.w3.org/TR/xslt20/# unprefixed-qnames. Đặt không gian tên mặc định bằng 'xmlns =" ​​... "' chỉ cấu hình không gian tên mặc định của các chữ XML trong biểu định kiểu, các biểu thức XPath không bị ảnh hưởng. – markusk

+0

@markusk Cảm ơn bạn đã làm rõ; Tôi đã không sử dụng không gian tên mặc định xpath-default, chắc chắn rằng nó sẽ có ích tại một số điểm trong tương lai của tôi! –

1

Nút có thể (nếu sử dụng XSLT 2.0+) cũng được áp dụng * bởi vì chúng nằm trong một không gian tên khác.

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

Điều này có thể chỉ là hữu ích hoặc đặc biệt hữu ích nếu không gian tên không xác định. Trong trường hợp này, hiệu ứng phụ tốt đẹp là nếu không gian tên được đánh dấu theo cách này thì các nút từ không gian tên khác không nhận được chú thích - điều này không được mong muốn trong trường hợp của chúng ta.

+1

@Jan: Cú pháp '*: name' chỉ được hỗ trợ trong XPath 2.0. –

+0

@Jan: Cũng lưu ý rằng bạn có thể sử dụng 'xpath-default-namespace' nếu bạn đang sử dụng XSLT 2.0 hoặc mới hơn, như được mô tả trong http://www.w3.org/TR/xslt20/#unprefixed-qnames. – markusk

+0

@Dimitre: Chắc chắn - xin lỗi, tôi quên thêm chi tiết đó (sử dụng). – Jan

Các vấn đề liên quan