2009-07-02 36 views
18

tôi đã có một số XML mà tuyên bố một không gian tên mà chỉ được sử dụng cho các thuộc tính, như thế này:XSL - sao chép các yếu tố nhưng loại bỏ không gian tên sử dụng (s)

<?xml version="1.0" encoding="UTF-8"?> 
<a xmlns:x="http://tempuri.com"> 
    <b> 
     <c x:att="true"/> 
     <d>hello</d> 
    </b> 
</a> 

Tôi muốn sử dụng XSL để tạo ra một bản sao các nút đã chọn và giá trị của chúng - loại bỏ các thuộc tính. Vì vậy, đầu ra mong muốn của tôi là:

<?xml version="1.0" encoding="UTF-8"?> 
<b> 
    <c /> 
    <d>hello</d> 
</b> 

tôi đã có một số XSL rằng hầu hết thực hiện điều này, nhưng tôi dường như không thể ngăn chặn nó đưa tờ khai không gian tên trong thành phần cấp cao nhất của đầu ra. XSL của tôi là:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:template match="/"> 
     <xsl:apply-templates select="https://stackoverflow.com/a/b"/> 
    </xsl:template> 

    <xsl:template match="node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="node()"/> 
     </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

Yếu tố đầu tiên của đầu ra là <b xmlns:x="http://tempuri.com"> thay vì <b>. Tôi đã cố gắng tuyên bố không gian tên trong XSL và đặt tiền tố trong danh sách exclude-result-prefixes, nhưng điều này dường như không có bất kỳ ảnh hưởng nào. Tôi đang làm gì sai?

CẬP NHẬT: Tôi đã tìm thấy rằng bằng cách khai báo không gian tên trong XSL và sử dụng thuộc tính extension-element-prefixes hoạt động, nhưng điều này có vẻ không đúng! Tôi đoán tôi có thể sử dụng điều này, nhưng tôi muốn biết tại sao exclude-result-prefixes không hoạt động!

CẬP NHẬT: Thực ra, có vẻ như giải pháp extension-element-prefixes này chỉ hoạt động với công cụ XSLT tích hợp của XMLSpy, không phải với MSXML.

Trả lời

9
<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" 
    xmlns:x="http://tempuri.com"> 
    <xsl:template match="/"> 
     <xsl:apply-templates select="https://stackoverflow.com/a/b"/> 
    </xsl:template> 

    <xsl:template match="*"> 
     <xsl:element name="{local-name(.)}"> 
      <xsl:apply-templates/> 
     </xsl:element> 
    </xsl:template> 

    <xsl:template match="@*"> 
     <xsl:copy/> 
    </xsl:template> 

    <!-- This empty template is not needed. 
Neither is the xmlns declaration above: 
    <xsl:template match="@x:*"/> --> 
</xsl:stylesheet> 

Tôi đã tìm thấy giải thích here.

Michael Kay viết:
loại trừ-Kết quả-tiền tố chỉ ảnh hưởng đến không gian tên sao chép từ stylesheet bởi một yếu tố kết quả theo nghĩa đen, nó không ảnh hưởng sao chép namespace từ các tài liệu nguồn.

+0

Thanks, điều này không làm việc (mặc dù "@ *" mẫu dường như không được yêu cầu), nhưng tôi nghĩ rằng "địa phương-name () "Chức năng khá chậm ..? –

+1

Tôi muốn XSLT 2.0! – Riri

+0

Gần như hoàn hảo, nhưng thuộc tính x: att bị thiếu từ đầu ra. Mẫu "@ *" không được gọi. Thử thêm trực tiếp trước . –

5
<xsl:stylesheet 
    version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:x="http://tempuri.com" 
    exclude-result-prefixes="x" 
> 

    <!-- the identity template copies everything 1:1 --> 
    <xsl:template match="@* | node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@* | node()" /> 
    </xsl:copy> 
    </xsl:template> 

    <!-- this template explicitly cares for namespace'd attributes --> 
    <xsl:template match="@x:*"> 
    <xsl:attribute name="{local-name()}"> 
     <xsl:value-of select="." /> 
    </xsl:attribute> 
    </xsl:template> 

</xsl:stylesheet> 
2

Điều này sẽ xóa không gian tên x khỏi đầu ra.

<xsl:namespace-alias result-prefix="#default" stylesheet-prefix="x" /> 

Hãy nhớ thực hiện hai việc khi bạn xử lý một không gian tên mặc định. Trước tiên, ánh xạ nó vào một cái gì đó trong thẻ biểu định kiểu và sau đó loại bỏ nó bằng cách sử dụng bí danh không gian tên.

4

Hãy thử điều này (lưu ý các thuộc tính copy-namespaces='no'):

<xsl:template match="node()"> 
    <xsl:copy copy-namespaces="no"> 
      <xsl:apply-templates select="node()"/> 
    </xsl:copy> 
</xsl:template> 
Các vấn đề liên quan