Chuyển đến nôi dung chính

Bằng việc nhấn Gửi, bạn đã đồng ý với các điều khoản sử dụng developerWorks Điều khoản sử dụng (tiếng Anh).

Khi bạn đăng nhập lần đầu tiên, một bản trích ngang trên developerWorks sẽ được tạo ra. Chọn các thông tin trong trích ngang của developerWorks để hiển thị công khai, bạn có thể sửa lại thông tin này bất cứ lúc nào. Tên, họ và tên hiển thị sẽ đi kèm với nội dung mà bạn gửi lên.

Thông tin gửi đi được đảm bảo an toàn.

  • Đóng [x]

Lần đầu tiên bạn đăng nhập vào trang developerWorks, một bản trích ngang được tạo ra cho bạn, bạn cần phải chọn một tên để hiển thị. Tên hiển thị của bạn sẽ đi kèm theo các nội dung mà bạn đăng tải trên developerWorks.

Tên hiển thị cần có từ 3 đến 30 ký tự. Tên xuất hiện của bạn phải là duy nhất trên trang Cộng đồng developerWorks và vì lí do an ninh nó không phải là địa chỉ email của bạn.

Bằng việc nhấn Gửi, bạn đã đồng ý với các điều khoản sử dụng developerWorks Điều khoản sử dụng (tiếng Anh).

Thông tin gửi đi được đảm bảo an toàn.

  • Đóng [x]

Tránh các lỗi XSLT thông thường

Thay đổi thói quen xấu thành mã XSLT tốt

Jirka Kosek, Nhà tư vấn, 自由职业者
Jirka Kosek là một nhà tư vấn XML làm việc tự do đồng thời kiêm giảng viên tại trường đại học Kinh tế ở Prague. Ông có hơn 10 năm kinh nghiệm trong việc cung cấp các khóa đào tạo và tư vấn XML. Jirka là một thành viên tích cực của một vài tổ chức tiêu thuẩn hóa bao gồm OASIS (DocBook TC and RELAX NG TC), tổ chức W3C (XSL WG) và ITS WG), và ISO/IEC JTC1/SC34 (DSDL, Topic Maps). Bạn có thể làm quen với các công việc và ý tưởng gần đây của ông ấy qua http://xmlguru.cz blog cá nhân.

Tóm tắt:  Làm giảng viên kiêm tư vấn, nên tôi đã chứng kiến rất nhiều đoạn mã XSLT đuợc viết rất nghèo nàn và có thiết kế rất tệ. Rất nhiều trong số các thói quen xấu này được lặp đi lặp lại nhiều lần và có thể gây ra các lỗ hổng nghiêm trọng trong mã XSLT. Trong bài viết này, xin hãy có một chút cảm nhận về những lỗi điển hình xuất hiện trong các bảng kiểu (stylesheet) và cách để khắc phục.

Ngày:  17 07 2009
Mức độ:  Trung bình Cũng sẵn có bằng  tiếng Anh PDF:  A4 và Thư (115KB | 10 pages)Tải Adobe® Reader®
Hoạt động:  2810 lần đọc
Góp ý kiến:  


Viết mã trình để nắm được những biến đổi XML trong XSLT thì dễ hơn rất nhiều so với việc viết trên các loại ngôn ngữ lập trình được dùng phổ biến khác. Nhưng ngôn ngữ XSLT có cú pháp và mẫu xử lý khác so với các loại ngôn ngữ lập trình truyền thống mà chúng ta phải mất thời gian để nắm được tất cả những sắc thái tinh tế của XSLT.

Bài viết này sẽ không phải là một bài hướng dẫn XSLT phức tạp và mở rộng.Thay vào đó, bài viết sẽ bắt đầu bằng việc giải thích các chủ đề gây ra những khó khăn lớn nhất cho các nhà phát triển XSLT và XML. Sau đó, bài viết sẽ chuyển sang các chủ đề liên quan đến toàn bộ việc thiết kế các bảng kiểu và sự thể hiện của chúng.

Làm việc với những không gian tên (namespace)

Các từ viết tắt hay dùng

  • HTML: Hypertext Markup Language
  • SOAP: Simple Object Access Protocol
  • W3C: World Wide Web Consortium
  • XHTML: Extensible Hypertext Markup Language
  • XML: Extensible Markup Language
  • XSLT: Extensible Stylesheet Language Transformation

Mặc dù các tài liệu XML có không gian tên ngày càng phổ biến, vẫn có sự khó khăn nào đó trong việc sử dụng nó trong các ngành công nghệ khác nhau. Rất nhiều tài liệu sử dụng các tiền tố để chỉ các phần tử trong một không gian tên, và điều này đã không hẳn gây ra sự khó khăn. Như trong Ví dụ 1 thể hiện một ttông điệp SOAP giản đơn mà sử dụng hai không gian tên — một tên cho vỏ SOAP (envelope) và một cho trọng tải (payload) thực.


Ví dụ 1. Tài liệu XML với các không gian tên

<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope"> 
 <env:Body>
  <p:itinerary
    xmlns:p="http://travelcompany.example.org/reservation/travel">
   <p:departure>
     <p:departing>New York</p:departing>
     <p:arriving>Los Angeles</p:arriving>
     <p:departureDate>2001-12-14</p:departureDate>
     <p:departureTime>late afternoon</p:departureTime>
     <p:seatPreference>aisle</p:seatPreference>
   </p:departure>
   <p:return>
     <p:departing>Los Angeles</p:departing>
     <p:arriving>New York</p:arriving>
     <p:departureDate>2001-12-20</p:departureDate>
     <p:departureTime>mid-morning</p:departureTime>
     <p:seatPreference/>
   </p:return>
  </p:itinerary>
 </env:Body>
</env:Envelope>

Khi các phần tử trong một bản tài liệu gốc có các tiền tố, thì rõ ràng chúng thuộc về một không gian tên. Mọi người sẽ không gặp vấn đề gì khi xử lý một tài liệu như vậy trong XSLT. Sẽ hiệu quả nếu ta sao chép các khai báo không gian tên từ tài liệu gốc trong bảng kiểu. Mặc dù bạn có thể sử dụng các tiền tố bất kỳ, nhưng thường sẽ thuận tiện hơn nếu sử dụng cùng các tiền tố như các tài liệu đầu vào phổ biến, như trong Ví dụ 2.


Ví dụ 2. Bảng kiểu truy cập thông tin trong một tài liệu có không gian tên

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0"
    xmlns:env="http://www.w3.org/2003/05/soap-envelope"
    xmlns:p="http://travelcompany.example.org/reservation/travel">

<xsl:templatematch="/">
  Departure location:
  <xsl:value-of select="/env:Envelope/env:Body/p:itinerary/p:departure/p:departing"/>
</xsl:template>

</xsl:stylesheet>

Như các bạn đã thấy, đoạn mã này đều khai báo có các tiền tố không gian tên envp trên phần tử gốc xsl:stylesheet. Những khai báo như vậy sẽ được theo sau bởi tất cả các phần tử trong bảng kiểu nhờ đó mà bạn có thể sử dụng chúng sau này trong bất cứ một biểu thức XPath nhúng nào. Cũng xin chú ý rằng trong các biểu thức XPath, bạn phải gắn cho tất cả các phần tử với một tiền tố không gian tên thích hợp. Nếu bạn quên đề cập một tiền tố trong bất cứ bước nào, biểu thức của bạn sẽ không trả lại kết quả gì — một lỗi mà rất khó tìm ra nguyên nhân.

Các tài liệu mà sử dụng các không gian tên thường là nguyên nhân gây ra sự cố khi việc sử dụng các không gian tên không được rõ ràng. Nếu bạn có nhiều phần tử trong một không gian tên, bạn có thể xác định không gian tên đó làm mặc định sử dụng các thuộc tính xmlns. Các phần tử ở không gian tên mặc định không được sử dụng các tiền tố, vì thế bạn có thể dễ dàng quên rằng chúng thực ra nằm trong một không gian tên. Hãy tưởng tượng rằng bạn phải chuyển đổi tài liệu XHTML trong Ví dụ 3.


Ví dụ 3. Tài liệu XHTML sử dụng một không gian tên mặc định

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Example XHTML document</title>
  </head>
  <body>
    <p>Sample content</p>
  </body>
</html>

Có thể là bạn mới chỉ đơn thuần liếc qua xmlns="http://www.w3.org/1999/xhtml", hoặc có thể là khai báo không gian tên mặc định này đã bị đứng trước bởi hàng tá các thuộc tính khác và bạn không thể nhìn thấy cái gì trong cột 167 — thậm chí là ngay cả trên màn hình rộng. Thông thường bạn có thể viết các biểu thức XPath như là /html/head/title, nhưng các biểu thức ấy sẽ khai báo một bộ nút trống rỗng, bởi vì tài liệu đầu vào không chứa bất cứ phần tử nào như title. Tất cả các phần tử trong tài liệu đầu vào đều thuộc về không gian tên http://www.w3.org/1999/xhtml và điều này được thể hiện trong các biểu thức XPath.

Để truy cập vào các phần tử được đặt không gian tên trong XPath, bạn phải xác định một tiền tố cho không gian tên của chúng. Thí dụ, nếu bạn muốn truy cập vào một tựa đề trong tài liệu XHTML mẫu, bạn phải xác định một tiền tố cho không gian tên XHTML, sau đó sử dụng tiền tố này trong tất cả các bước của XPath, như bảng kiểu ví dụ sau Ví dụ 4 thể hiện.


Ví dụ 4. Việc chuyển đổi phải sử dụng các tiền tố không gian tên cho cả các tài liệu đầu vào sử dụng một không gian tên mặc định

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0"
    xmlns:h="http://www.w3.org/1999/xhtml">

<xsl:templatematch="/">
  Title of document:
  <xsl:value-of select="/h:html/h:head/h:title"/>
</xsl:template>

</xsl:stylesheet>

Một lần nữa, bạn phải rất cẩn thận về các tiền tố trong các biểu thức XPath. Chỉ một tiền tố bị thiếu, là bạn đã phải nhận kết quả sai.

Không may là phiên bản XSLT 1.0 không có khái niệm nào tương đương với khái niệm không gian tên mặc định. Vì thế bạn phải lặp đi lặp lại nhiều lần các tiền tố không gian tên. Vấn đề này đã được điều chỉnh trong phiên bản XSLT 2.0. Ở phiên bản này bạn có thể định rõ một không gian tên mặc định mà sau đó có thể áp dụng cho những phần tử chưa có tiền tố trong một biểu thức XPath. Trong phiên bản XSLT 2.0, bạn có thể đơn giản hóa bảng kiểu trước đó như trong Ví dụ 5.


Ví dụ 5. Khai báo của không gian tên mặc định XPath trong XSLT 2.0

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="2.0"
    xpath-default-namespace="http://www.w3.org/1999/xhtml">

<xsl:templatematch="/">
  Title of document:
  <xsl:value-of select="/html/head/title"/>
</xsl:template>

</xsl:stylesheet>


Việc sử dụng không đúng hàm kiểm tra text()

Hầu hết các bảng kiểu đều chứa hàng tá các mẫu đơn giản có vai trò xử lý các thành phần lá trong các văn bản đầu vào. Thí dụ, bạn lưu trữ một giá trong một phần tử:

<price>124.95</price>

và bạn muốn xử lý nó như một đoạn mới trong HTML với số tiền và một nhãn hiệu được thêm vào:

<p>Price: 124.95 USD</p>

Trong rất nhiều bảng kiểu mà tôi đã xem, các mẫu có chức năng này có thể bị hỏng thảm hại. Nguyên nhân là do bởi việc sử dụng hàm kiểm tra nút text() bên trong mẫu đó mà có 99% trường hợp sẽ dẫn tới việc đoạn mã bị hỏng. Mẫu sau có vấn đề gì không?

<xsl:templatematch="price">
  <p>Price: <xsl:value-of select="text()"/> USD</p>
</xsl:template>

Biểu thức XPath bên trong xsl:value-of hướng dẫn là cách viết gọn cho biểu thức child::text(). Biểu thức này lựa chọn tất cả các nút văn bản giữa những con của phần tử <price>. Thông thường chỉ có một nút như vậy và mọi thứ sẽ làm việc như mong đợi. Tuy nhiên, hãy tưởng tượng rằng bạn đặt một chú thích hay một chỉ dẫn xử lý vào giữa phần tử <price> như sau:

<price>12<!-- I'm a comment. I should be ignored. -->4.95</price>

Biểu thức bây giờ sẽ trả lại hai nút văn bản: 124.95. Nhưng ý nghĩa của xsl:value-of là nó sẽ chỉ trả lại nút đầu tiên đã được xác định. Trong trường hợp này, bạn sẽ nhận được kết quả xử lý sai:

<p>Price: 12 USD</p>

Bởi vì xsl:value-of muốn một nút đơn, bạn phải sử dụng nó với một biểu thức mà trả lại đúng một nút. Trong rất nhiều trường hợp, một tham chiếu tới nút hiện hành (.) là cách tiếp cận đúng. Vì thế, hình thức đúng của mẫu trên là:

<xsl:templatematch="price">
  <p>Price: <xsl:value-of select="."/> USD</p>
</xsl:template>

nút hiện hành (.) bây giờ trả lại toàn bộ phần tử <price>. Chỉ dẫn xsl:value-of sẽ tự động trả lại giá trị chuỗi của một nút làm điểm ghép nối của tất cả các nút văn bản con. Cách tiếp cận như vậy đảm bảo rằng bạn sẽ luôn luôn nhận được toàn bộ nội dung của một phần tử bất kể các chú thích đi cùng, các chỉ dẫn xử lý, hoặc là các phần tử phụ.

Trong phiên bản XSLT 2.0, ý nghĩa của chỉ dẫn xsl:value-of bị thay đổi, và nó trả lại 1 giá trị chuỗi của tất cả các nút đã đi qua — chứ không chỉ mỗi nút đầu tiên. Nhưng sẽ tốt hơn nếu ta tham chiếu phần tử đó cho nội dung mà sẽ được trả lại cho các nút văn bản của nó. Bằng cách này, đoạn mã sẽ không bị gãy khi các phần tử nhỏ mới được thêm vào để cung cấp những chú ý nhỏ.


Đừng đánh mất nút ngữ cảnh

Mỗi mẫu (xsl:template) hay phép lặp lại (xsl:for-each) được giải thích với một nút hiện hành. Tất cả các biểu thức XPath đều được đánh giá bắt đầu từ nút hiện hành này. Nếu bạn bắt đầu một biểu thức XPath với /, biếu thức đó sẽ không được đánh giá với nút hiện hành, mà thay vào đó, việc đánh giá sẽ được bắt đầu tại nút gốc của tài liệu. Kết quả của các biểu thức như vậy sẽ luôn luôn giống nhau, và nó sẽ không được liên hệ với nút hiện hành.

Hãy tưởng tượng rằng bạn muốn xử lý một hóa đơn trong Ví dụ 6.


Ví dụ 6. Hóa đơn mẫu

<invoice>
  <item>
    <description>Pilsner Beer</description>
    <qty>6</qty>
    <unitPrice>1.69</unitPrice>
  </item>
  <item>
    <description>Sausage</description>
    <qty>3</qty>
    <unitPrice>0.59</unitPrice>
  </item>
  <item>
    <description>Portable Barbecue</description>
    <qty>1</qty>
    <unitPrice>23.99</unitPrice>
  </item>
  <item>
    <description>Charcoal</description>
    <qty>2</qty>
    <unitPrice>1.19</unitPrice>
  </item>
</invoice>

Nếu bạn quên không viết các biểu thức tương ứng với nút hiện hành, bạn sẽ có thể dễ tạo ra một bảng kiểu sai, như trong Ví dụ 7.


Ví dụ 7. Mẫu bảng kiểu kém vì đã mất đi ngữ cảnh

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:templatematch="/">
  <html>
    <head>
      <title>Invoice</title>
    </head>
    <body>
      <table>
        <xsl:for-each select="/invoice/item">
          <tr>
            <td><xsl:value-of select="/invoice/item/description"/></td>             
            <td><xsl:value-of select="/invoice/item/qty"/></td>
            <td><xsl:value-of select="/invoice/item/unitPrice"/></td>
          </tr>          
        </xsl:for-each>
      </table>      
    </body>
  </html>  
</xsl:template>

Biểu thức /invoice/item trong xsl:for-each đã lựa chọn đúng tất cả các mặt hàng trong hóa đơn. Nhưng các biểu thức bên trong xsl:for-each lại sai bởi vì chúng bắt đầu bằng /, điều đó có nghĩa là chúng là tuyệt đối. Các biểu thức như vậy luôn luôn khai báo lại một mô tả, số lượng, và giá của mặt hàng đầu tiên (Ghi nhớ từ mục trước xsl:value-of chỉ trả lại nút đầu tiên từ một bộ nút), bởi vì một biểu thức tuyệt đối không phụ thuộc vào nút hiện hành, tương ứng với món hàng đang được xử lý.

Để dễ dàng sửa lỗi này, hãy sử dụng một biểu thức tương ứng bên trong xsl:for-each, như là trong Ví dụ 8.


Ví dụ 8. Sử dụng các biểu thức XPath tương ứng bên trong phần lặp lại

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:templatematch="/">
  <html>
    <head>
      <title>Invoice</title>
    </head>
    <body>
      <table>
        <xsl:for-each select="/invoice/item">
          <tr>
            <td><xsl:value-of select="description"/></td>             
            <td><xsl:value-of select="qty"/></td>
            <td><xsl:value-of select="unitPrice"/></td>
          </tr>          
        </xsl:for-each>
      </table>      
    </body>
  </html>  
</xsl:template>

</xsl:stylesheet>


Hãy tránh các đường liên kết gãy trong các trình duyệt không phải của Microsoft

XSLT là công cụ rất tốt để thực hiện các công việc thông thường tự động. Một công việc tay chân tốn sức và buồn tẻ như là việc chuẩn bị một bảng nội dung. Với XSLT, bạn có thể tạo ra cái bảng đó một cách tự động. Bạn chỉ cần đơn giản tạo ra các mẫu neo (anchor), sau đó các liên kết tham chiếu lại chúng. Trong HTML, bạn tạo ra một mẫu neo đơn thuần bằng cách đặt một từ định danh duy nhất bên trong thuộc tính id:

<div id="label">…</div>

Khi bạn xây dựng một liên kết quay lại mẫu neo này, thêm label sau một từ định danh mảnh (#) để chỉ thị rằng đây là một đường liên kết tới một nơi cụ thể bên trong tài liệu:

<a href="#label">link to …</a>

Một bảng kiểu thực sự thông thường sẽ cho ra các nhãn (label) và đường liên kết bằng việc sử dụng generate-id() chức năng hay một từ định danh đã được cung cấp trong tài liệu đầu vào.

Vấn đề với công việc liên kết này thực ra không phải trong chính XSLT mà trong một số trình duyệt Web quá thông minh. Tôi đã thấy rất nhiều bảng kiểu mà trong đó một từ định danh (#) được thêm vào mẫu neo một cách sai sót. Sản phẩm xử lý ra của bảng kiểu đó được kiểm tra chỉ trong Window® Internet Explorer®. Thật không may là, Internet Explorer có thể khôi phục nhiều lỗi trong mã HTML, vì thế sẽ không có vấn đề gì về liên kết từ hình phối cảnh của người dùng. Nhưng nếu bạn cũng thử trang đó trên các trình duyệt như là Mozilla Firefox hay Opera, các đường liên kết đó sẽ bị hỏng, bởi vì các trình duyệt này không thể khôi phục từ sự vượt quá #.

Để tránh các lỗi tương tự khác, cách tốt nhất là bạn kiểm tra sản phẩm xử lý đầu ra bằng bảng kiểu của bạn trên nhiều trình duyệt.


Đơn giản hóa các bảng kiểu bằng cách thay đổi nút ngữ cảnh

Nếu bạn xử lý các tài liệu kinh doanh hay XML định hướng dữ liệu, thì thông thường không phải dựa hoàn toàn trên một cơ chế mẫu mà chỉ lượm nội dung yêu cầu và lắp ráp nó vào một hình thức như mong muốn trong một mẫu rộng. Hãy tưởng tượng rằng bạn muốn xử lý một hóa đơn trong Ví dụ 9.


Ví dụ 9. Hóa đơn với cấu trúc phức tạp

<Invoice>
  <ID>IN 2003/00645</ID>
  <IssueDate>2003-02-25</IssueDate>
  <TaxPointDate>2003-02-25</TaxPointDate>
  <OrderReference>
    <BuyersID>S03-034257</BuyersID>
    <SellersID>SW/F1/50156</SellersID>
    <IssueDate>2003-02-03</IssueDate>
  </OrderReference>
  <BuyerParty>
    <Party>
      <Name>Jerry Builder plc</Name>
      <Address>
	<StreetName>Marsh Lane</StreetName>
	<CityName>Nowhere</CityName>
	<PostalZone>NR18 4XX</PostalZone>
	<CountrySubentity>Norfolk</CountrySubentity>
      </Address>
      <Contact>Eva Brick</Contact>
    </Party>
  </BuyerParty>
  …
</Invoice>

Một bản kiểu điển hình cho xử lý tài liệu này (Xem Ví dụ 10) Sẽ bao gồm rất nhiều đường dẫn trong các biểu thức XPath, bởi vì rất nhiều thông tin được đặt trong cùng một phần của cây XML đầu vào.


Ví dụ 10. Bảng kiểu này sử dụng rất nhiều các mã XPath lặp đi lặp lại

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:templatematch="/">
  <html>
    <head>
      <title>Invoice #<xsl:value-of select="/Invoice/ID"/></title>
    </head>
    <body>
      <h1>Invoice #<xsl:value-of select="/Invoice/ID"/>
          issued on <xsl:value-of select="/Invoice/IssueDate"/></h1>

      <div>
        <h2>Buyer:</h2>

        <p>
          <b><xsl:value-of select="/Invoice/BuyerParty/Party/Name"/></b>
        </p>

        <p>Address:<br/>
          <xsl:value-of select="/Invoice/BuyerParty/Party/Address/StreetName"/><br/>
          <xsl:value-of select="/Invoice/BuyerParty/Party/Address/CityName"/><br/>
          <xsl:value-of select="/Invoice/BuyerParty/Party/Address/PostalZone"/>
        </p>
        
        <p>Contact person: <xsl:value-of select="/Invoice/BuyerParty/Party/Contact"/></p>
        …
      </div>
    </body>
  </html>  
</xsl:template>

</xsl:stylesheet>

Các mã lặp lại đó trong biểu thức XPath là dài dòng — bạn phải lặp lại chúng nhiều lần. Chúng cũng cho chấy một gánh nặng sau này. Bất cứ những thay đổi nào đối với cấu trúc của tài liệu đầu vào tạo ra nhiều nơi hơn mà ở đó bạn phải điều chỉnh biểu thức. Bạn có thể đơn giản hóa bảng kiểu bằng cách nhân tố hóa một phần chung của các biểu thức. Bạn làm được điều này bằng cách sử dụng những chỉ dẫn làm thay đổi nút hiện hành — xsl:template and xsl:for-each. Bảng kiểu trong Ví dụ 11chứa ít thông tin lặp lại hơn một cách đáng kể.


Ví dụ 11. Bảng kiểu với các đường đường dẫn XPath đã được nhân tố hóa.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:templatematch="Invoice">
  <html>
    <head>
      <title>Invoice #<xsl:value-of select="ID"/></title>
    </head>
    <body>
      <h1>Invoice #<xsl:value-of select="ID"/>
          issued on <xsl:value-of select="IssueDate"/></h1>

      <div>
        <h2>Buyer:</h2>

        <xsl:for-each select="BuyerParty/Party">
          <p>
            <b><xsl:value-of select="Name"/></b>
          </p>

          <xsl:for-each select="Address">
            <p>Address:<br/>
              <xsl:value-of select="StreetName"/><br/>
              <xsl:value-of select="CityName"/><br/>
              <xsl:value-of select="PostalZone"/>
            </p>
          </xsl:for-each>

          <p>Contact person: <xsl:value-of select="Contact"/></p>
        </xsl:for-each>

        …
      </div>
    </body>
  </html>  
</xsl:template>

</xsl:stylesheet>

Tôi đã thay đổi điểm khớp trên mẫu từ / tới Invoice do đó tôi không phải lặp lại tên phần tử gốc này ở đầu của mỗi biểu thức XPath. Bên trong mẫu, tôi đã sử dụng xsl:for-each để tạm thời thay đổi nút hiện hành thành người mua (BuyerParty/Party) và bên trong nó lại một lần nữa là địa chỉ (Address). Nó có vẻ là lạ khi sử dụng xsl:for-each cho các phần tử không lặp lại, nhưng không có gì sai ở đây cả: Phần lặp lại sẽ được gọi lên chỉ một lần nhưng với một nút hiện hành đã thay đổi


Xử lý nội dung hỗn hợp

Nội dung hỗn hợp thông thường xuất hiện trong XML định hướng tài liệu. Nội dung hỗn hợp là một cấu trúc mà ở đó, một phần tử chứa cả phần tử và nút văn bản như mục con. Một ví dụ điển hình của nội dung hỗn hợp là một đoạn văn có chứa văn bản với những đánh dấu phụ như là nhấn mạnh, hay các liên kết:

<para><emphasis>Douglas Adams</emphasis> was an English author, comic
radio dramatist, and musician. He is best known as the author of the
<link url="http://en.wikipedia.org/wiki/The_Hitchhiker's_Guide_to_the_Galaxy">Hitchhiker's
Guide to the Galaxy</link> series.</para>

Việc xử lý nội dung hỗn hợp trong trật tự của tài liệu là rất quan trọng, nếu không bạn sẽ có thể phải nhận kết quả sai hoàn toàn, với các phần câu bị thay đổi trật tự. Cách thông thường nhất để xử lý nội dung hỗn hợp là bằng cách gọi xsl:apply-templates trên phần tử mà có nội dung hỗn hợp hoặc gọi tất cả các mục con của phần tử đó. Các mẫu theo sau có thể xử lý đánh dấu đã được nhúng vào như nhấn mạnh và những liên kết.

Tôi đã xem nhiều bảng kiểu sử dụng cách tiếp cận "lượm lặt" ("cherry-picked") cho việc xử lý nội dung hỗn hợp. Cách tiếp cận này rất phù hợp với các tài liệu có cấu trúc chuẩn mực, nhưng nội dung hỗn hợp thường thay đổi trong cấu trúc bên trong của nó và rất khó để nắm bắt được điều này một cách đúng đắn. Vì thế, bất cứ khi nào bạn thấy nội dung hỗn hợp, hãy cố gắng quên đi xsl:value-ofxsl:for-each và tập trung vào các mẫu.


Tính không hiệu quả trong bảng kiểu của bạn

Nếu bạn viết những biến đổi nhỏ thực thi trên các chuỗi dữ liệu nhỏ — ví dụ như là một lớp xem trong ứng dụng Web — mà bạn đang không mấy tập trung vào sự thể hiện cách biến đổi của nó, bởi vì quá trình này thông thường rất nhỏ so với toàn bộ quá trình lớn. Nhưng khi một bảng kiểu XSLT thể hiện các hoạt động hay công việc phức tạp trên một tài liệu đầu vào rộng, thì đã đến lúc bạn phải bắt đầu nghĩ về ảnh hưởng của cấu trúc sử dụng trong bảng kiểu đến tính hiệu quả.

Nói chung, thật khó để đánh giá chỉ riêng mã XSLT bởi vì nó phải phụ thuộc vào việc triển khai XSLT cụ thể — và liệu nó có nắm được các mã tốt không và có thể tăng tốc nó lên bằng cách sử dụng một bộ tối ưu nào đó.

Bất kể vậy, có nhiều điểm tốt trong các bảng kiểu thực tế. Nếu bạn muốn cứu hành tinh này, hãy sử dụng trục con cháu (//) một cách cẩn thận. Khi bạn sử dụng //, bộ xử lý XSLT sẽ phải kiểm tra toàn bộ cây (hoặc cây nhỏ). Trong các tài liệu rộng hơn, đây có thể là một hoạt động hết sức tốn kém. Sẽ tốt hơn nếu viết nhiều các biểu thức cụ thể hơn mà định rõ nơi để tìm các nút. Ví dụ, để lấy địa chỉ người mua, tốt hơn hết nên viết /Invoice/BuyerParty/Party/Address thay vì //BuyerParty//Address hoặc thậm chí //Address. Biến thể đầu tiên là nhanh hơn nhiều bởi vì chỉ ra có một phần nhỏ các nút là phải kiểm tra trong suốt quá trình đánh giá. Các biểu thức được chỉ đích như vậy cũng sẽ không bị ảnh hưởng nhiều bởi sự tiến triển cấu trúc của tài liệu, quá trình mà các phần tử mới mang cùng một tên nhưng khác nghĩa có thể được thêm vào các ngữ cảnh khác nhau trong tài liệu đầu vào.

Một cách khác khi bạn làm việc nhiều với tìm kiếm, hãy định ra một khóa tìm kiếm sử dụng xsl:key, sau đó sử dụng key() chức năng để thực hiện việc tìm kiếm.

Bạn có thể tạo ra rất nhiều bộ tối ưu hóa, nhưng ảnh hưởng của chúng lại phụ thuộc vào bộ xử lý XSLT mà bạn sử dụng.


XSLST phiên bản 1.0 hay phiên bản 2.0?

Phiên bản XSLT nào mà bạn sử dụng phụ thuộc vào một vài phần tử, nhưng nói chung, tôi khuyên bạn nên sử dụng phiên bản 2.0. Phiên bản mới nhất của ngôn ngữ có chứa rất nhiều những chỉ dẫn và chức năng mới mà có thể đơn giản hóa rất nhiều tác vụ — mã ngắn hơn và trực tiếp sẽ luôn luôn dễ dàng hơn để duy trì. Vả lại, trong phiên bản XSLT 2.0, bạn có thể viết các bảng kiểu nhận biết lược đồ, sử dụng lược đồ để xác nhận các tài liệu cả đầu vào lẫn đầu ra.Các bảng kiểu nhận biết lược đồ có thể sử dụng thông tin có chứa một lược đồ để tự động tìm ra các loại sai lệch và nhầm lẫn trong bảng kiểu của bạn.


Kết luận

Bài này đã bàn một số lĩnh vực xu trong hướng đầy thách thức của XSLT. Tôi hy vọng rằng bây giờ bạn đã có một kiến thức sâu rộng hơn về một số đặc trưng của XSLT và bạn sẽ có thể viết các bảng kiểu XSLT tốt hơn.


Tài nguyên

Học tập

  • What kind of language is XSLT? (Michael Kay, developerWorks,April 2005): Đặt XSLT vào văn bản với bài phân tích, đánh giá giải thích vai trò và thiết kế của XSLT.

  • Planning to upgrade XSLT 1.0 to 2.0 (David Marston, Joanne Tong, Henry Zongaro; developerWorks; Tháng 10, 2006 - Tháng 7, 2007): Trong loạt bài 7 phần này, hãy khám phá những đặc tính mới của XSLT 2.0.

  • New to XML: Kiểm tra bài này cho sự bắt đầu với XML

  • XML technical library: Xem vùng developerWorks XML cho một loạt các bài viết và hướng dẫn kĩ thuật, bài hướng dẫn, các tiêu chuẩn, và những cuốn sách đỏ IBM

  • IBM XML certification: Tìm ra cách bạn có thể trở thành một nhà phát triển được chứng chỉ của IBM về XML và các công nghệ liên quan.

  • developerWorks technical events and webcasts: Các sự kiện về công nghệ.

  • The technology bookstore: Duyệt những sách về các chủ đề kĩ thuật

  • developerWorks podcasts: Nghe các bài phỏng vấn và thảo luận hay giành cho các nhà phát triển phần mềm.

Lấy sản phẩm và công nghệ

  • Bản phần mềm dùng thử đánh giá của IBM: Hãy xây dựng cho bạn một dự án mới với phần mềm dùng thử có thể tải xuống trực tiếp từ developerWorks, bao gồm các công cụ phát triển ứng dụng và các sản phẩm phần mềm trung gian từ DB2®, Lotus®, Rational®, Tivoli®, và WebSphere®.

Thảo luận

Đôi nét về tác giả

Jirka Kosek là một nhà tư vấn XML làm việc tự do đồng thời kiêm giảng viên tại trường đại học Kinh tế ở Prague. Ông có hơn 10 năm kinh nghiệm trong việc cung cấp các khóa đào tạo và tư vấn XML. Jirka là một thành viên tích cực của một vài tổ chức tiêu thuẩn hóa bao gồm OASIS (DocBook TC and RELAX NG TC), tổ chức W3C (XSL WG) và ITS WG), và ISO/IEC JTC1/SC34 (DSDL, Topic Maps). Bạn có thể làm quen với các công việc và ý tưởng gần đây của ông ấy qua http://xmlguru.cz blog cá nhân.

Hướng dẫn về "Phản ánh nội dung không thích hợp

Phản ánh về nội dung không thích hợp

Cám ơn. Nhận xét này sẽ được báo cho người chủ mục tin.


Hướng dẫn về "Phản ánh nội dung không thích hợp

Phản ánh về nội dung không thích hợp

Gửi phản ánh bị lỗi. Làm ơn thử lại sau.


developerWorks: Đăng nhập

Nếu bạn chưa có định danh (ID) và mật khẩu của IBM, đăng ký tại đây.


Bạn quên định danh?


Bạn quên mật khẩu?
Đổi mật khẩu


Bằng việc nhấn Gửi, bạn đã đồng ý với các điều khoản sử dụng developerWorks Điều khoản sử dụng (tiếng Anh).

 


Khi bạn đăng nhập lần đầu tiên, một bản trích ngang trên developerWorks sẽ được tạo ra. Chọn các thông tin trong trích ngang của developerWorks để hiển thị công khai, bạn có thể sửa lại thông tin này bất cứ lúc nào. Tên, họ và tên hiển thị sẽ đi kèm với nội dung mà bạn gửi lên.

Choose your display name

Lần đầu tiên bạn đăng nhập vào trang developerWorks, một bản trích ngang được tạo ra cho bạn, bạn cần phải chọn một tên để hiển thị. Tên hiển thị của bạn sẽ đi kèm theo các nội dung mà bạn đăng tải trên developerWorks.

Tên hiển thị cần có từ 3 đến 30 ký tự. Tên xuất hiện của bạn phải là duy nhất trên trang Cộng đồng developerWorks và vì lí do an ninh nó không phải là địa chỉ email của bạn.

(Độ dài phải từ 3 đến 31 ký tự)


Bằng việc nhấn Gửi, bạn đã đồng ý với các điều khoản sử dụng developerWorks Điều khoản sử dụng (tiếng Anh).

 


Chấm điểm bài này

Bình luận

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=70
Zone=Nguồn mở
ArticleID=413537
ArticleTitle=Tránh các lỗi XSLT thông thường
publish-date=07172009
author1-email=jirka@kosek.cz
author1-email-cc=