Định vị các phần dữ liệu cụ thể của tài liệu XML với XPath, Phần 1

Sử dụng XPath để định vị và xác định từng phần của tài liệu XML

XML là một kiểu định dạng dữ liệu hiệu quả và linh hoạt. Nhưng mục đích chính của XML là khả năng không giới hạn cho việc tìm kiếm một cách nhanh và hiệu quả yêu cầu trong toàn bộ một tài liệu. XPath cung cấp khả năng để dễ dàng tham chiếu đến một văn bản, đến các thành phần và các thuộc tính của tài liệu — và không yêu cầu nhiều thời gian để nghiên cứu. Thêm vào đó, XPath là giải pháp để xây dựng từ vựng và công nghệ của XML ví dụ như XSL và XQuery. Bài hướng dẫn này sẽ dạy bạn các nguyên tắc cơ bản của XPath bao gồm tất cả các khái niệm và các đối tượng lựa chọn khác nhau dưới dạng các ví dụ và các bài tập thực hành.

Brett McLaughlin , Tác giả, biên tập, O'Reilly Media

Brett McLaughlin là tác giả có nhiều sách bán chạy nhất và được trao tặng nhiều giải thưởng cao. Các sách của ông đã bán với hơn 100,000 bản gồm các thể loại về ngôn ngữ lập trình, home theater, phân tích và thiết kế. Ông đã và đang vẫn tiếp tục công việc viết, chủ biên và xuất bản các sách về công nghệ trong hơn một thập niên vừa qua, ngoài các công việc yêu thích là viết sách ông còn tham gia chơi guitar và nô đùa với hai cậu con trai của ông tại nhà cùng với người vợ của ông



20 05 2009

Trước khi bạn bắt đầu

Tìm hiểu về nội dung của bài hướng dẫn này.

Giới thiệu về bài hướng dẫn

Trong phần 1 của bài học này giới thiệu chi tiết về XPath, mô tả làm thế nào để bạn có thể xác định các vùng riêng biệt của tài liệu XML sử dụng cú pháp dưới dạng thư mục. Bạn sẽ được học về cú pháp của XPath và sẽ làm việc với các công cụ để bạn hiểu rõ hơn về XPath. Sau khi bạn kết thúc bài hướng dẫn này, bạn sẽ có những kiến thức cơ bản về XPath. Từ đó bạn sẽ hiểu được những khái niệm cơ bản về các nút và biết cách dùng XPaths một cách hiệu quả và bạn có thể kết hợp các kết quả khác nhau của XPaths vào làm một.

Mục tiêu bài hướng dẫn

Các thuật ngữ viết tắt

  • API: giao diện lập trình ứng dụng
  • HTML: Ngôn ngữ đánh dấu siêu văn bản
  • URI: Uniform Resource Identifier
  • W3C: World Wide Web Consortium
  • XML: Ngô ngữ đánh dấu mở rộng
  • XSL: Extensible Stylesheet Language
  • XSLT: Các phép biến đổi XSL

Bài hướng dẫn này giúp bạn một cách có hệ thống về các khía cạnh của XPath API bắt đầu từ cú pháp cơ bản đến các xử lý thông dụng nhất. Bao gồm sử dụng đường dẫn định vị khác nhau và diễn tả làm cách nào định vị xử lý biểu thức XPath liên quan.

Bạn cũng sẽ bắt đầu tìm hiểu sự liên quan của XPath tới các khái niệm và công nghệ khác của XML như XSL, XSLT và XQuery. Có thể bạn chưa thành thạo XPath trong công việc hiện tại của bạn nhưng bạn cũng sẽ có thể áp dụng nó để giải quyết các vấn đề của công việc thực tế.

Điều kiện tiên quyết

Bài hướng dẫn được viết cho các tác giả và các lập trình viên làm việc về XML. Bạn có thể trở thành thành viên của bài hướng dẫn để bạn có thể đọc, viết và thực thi được XML. Bạn nên tìm hiểu các khái niệm liên quan, bao gồm:

  • Các thành phần
  • Các thuộc tính
  • Văn bản
  • Thành phần gốc

Tham khảo phần Mô hình đối tượng tài liệu (DOM) để hiểu rõ hơn Các nút, điều này là không bắt buộc. Nếu bạn muốn đọc tìm hiểu về DOM, ghé thăm Tài nguyên tìm kiếm một vài đường liên kết liên quan.

Bài hướng dẫn này đề cập đến một số API khác như XSL, XSLT và XPath. Nếu có sự hiểu biết trước về những vấn đề này thì có ích hơn mặc dù điều này là không bắt buộc. Để có nhiều thông tin hơn về những vấn đề này, tham khảo Tài nguyên của bài học.


Cài đặt môi trường làm việc của bạn để áp dụng cho các ví dụ

Bạn sẽ làm việc với tài liệu XML trong suốt bài hướng dẫn này. Bạn sẽ cần phải sử dụng tài liệu này trên máy của bạn và cần phải biết rõ cấu trúc cơ bản của tài liệu. Thêm vào đó, bạn sẽ cần phải có công cụ để thực thi XPath và trả lại kết quả tương ứng với công việc bạn lựa chọn thực hiện. Trong phần này trình bày làm thế nào để có thể làm việc được trên môi trường làm việc cá nhân của bạn vì thế có thể thực hiện theo các ví dụ hướng dẫn của bài hướng dẫn.

Các công cụ để đánh giá XPath được phân loại tương ứng cho từng hệ thống xử lý khác nhau. Một vài công cụ làm việc tốt hơn khi bài tải tệp dưới dạng EXE và chạy trên nền của Microsoft® Windows® không làm việc trên hệ điều hành Mac OS X. Tương tự, các công cụ để làm việc với XPath trên hệ điều hành Mac OS X không thể chạy được trên hệ điều hành Windows. Trong khi bạn sử dụng Java™ các chương trình và các lớp được tạo ra độc lập về mặt hệ thống để có thể làm việc được với XPath, bài hướng dẫn này tập trung nhiều vào XPath chứ không quan tâm nhiều về ngôn ngữ lập trình.

Các phần tiếp theo sẽ mô tả cách để làm việc với công cụ mà cho phép làm việc với XPath trên cả hai hệ điều hành Windows và Mac OS X. Bạn hãy lựa chọn phần mà bạn muốn tìm hiểu. Với mỗi phần bạn đều có công cụ, tất cả các cú pháp và các ví dụ xuyên suốt của toàn khóa học để có thể làm việc. Bạn sẽ sử dụng công cụ của bạn để đánh giá các XPath.

Đánh giá XPaths trên Windows

Một trong các công cụ tốt nhất để làm việc với XPath trên Windows là Stylus Studio (tham khảo tại tài nguyên tới trang web của Stylus Studio và tải công cụ về). Tải bất kỳ phiên bản nào của Stylus Studio, gồm: Trial, — Enterprise Suite, Professional Suite, hoặc Home Edition — và sau đó cài đặt chúng ra trên máy của bạn tương ứng.

Mỗi lần bạn cài đặt Stylus Studio, phải chắc chắn rằng bạn có thể mở chương trình và tải được tài liệu XML vào để bạn có thể làm việc được với XPaths. Màn hình làm việc của bạn trông tương tự như Hình 1.

Hình 1. Stylus Studio cho phép bạn có thể đánh giá làm việc với XPath
Stylus Studio provides for XPath 2.0 experimentation

Đánh giá XPaths trên Mac OS X

Các công cụ để làm việc với XPath trên Mac OS X — không cần sử dụng các lớp của Java — là ít được quan tâm và sử dụng hơn so với các phiên bản của Windows. Công cụ sử dụng hiệu quả nhất để học XPath là AquaPath, là thuộc loại mã nguồn mở và có thể được tải miễn phí (ghé thăm trang tải về tại Tài nguyên). Tải AquaPath như là ảnh của đĩa và đơn giản thực hiện di chuyển ứng dụng AquaPath từ chỗ cài đặt tới thư mục các ứng.

Nháy đúp chuột vào ứng dụng AquaPath được cài đặt mới, và bạn nên tiếp cận màn hình của ứng dựng, có dạng như sau Hình 2.

Hình 2. AquaPAth cùng cấp cách đánh giá XPath trên hệ điều hành Mac OS X
Type your XPaths right into the XPath text box

Có thể trông không giống như trên nhưng khi đó bạn có thể bắt đầu tải các tài liệu XML và làm việc trong XPaths, công cụ này — giống như Stylus Studio — nên đáng để bạn bỏ thời gian để nghiên cứu.

Tài liệu kiểm tra XML

XPath là tốt hơn khi làm việc về XML so với bất kỳ ngôn ngữ lập trình nào. Vì thế mà trong khi hầu hết các ngôn ngữ lập trình cơ bản sử dụng XPath dưới dạng API kể từ Java đến ngôn ngữ C# thì bài hướng dẫn này tập trung vào việc đánh giá XPaths (thông qua công cụ AqualPath hoặc Stylus Studio) tương ứng với các tài liệu XML

Ví dụ 1 hiển thị một phần của tài liệu XML, là tệp Ant được xây dựng từ bộ phân tích Java Apache Xerces2. Toàn bộ tài liệu này rất nhiều nhưng phần này chỉ hiển thị một vài trang ví dụ. Tuy nhiên bạn có thể tải toàn bộ tài liệu XML từ Tài nguyên.

Ví dụ 1. Ví dụ tài liệu XML cho khóa học
<?xml version="1.0"?>
<!--
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
-->
<!-- ===================================================================

Read the README file for build instruction.

Authors:
  Stefano Mazzocchi <stefano@apache.org>
  Anupam Bagchi     <abagchi@apache.org>
  Andy Clark, IBM

   $Id: build.xml 567790 2007-08-20 19:16:53Z mrglavas $

==================================================================== -->
<project default="usage" basedir=".">
	
  <!-- Xerces Java directories -->
  <property name="build.dir" value="./build"/>
  <property name="data.dir" value="./data"/>
  <property name="docs.dir" value="./docs"/>
  <property name="samples.dir" value="./samples"/>
  <property name="src.dir" value="./src"/>
  <property name="tests.dir" value="./tests"/>
  <property name="tools.dir" value="./tools"/>

  <!-- enable compilation under JDK 1.4 and above -->
  <taskdef name="xjavac" classname="org.apache.xerces.util.XJavac">
    <classpath>
      <pathelement location="${tools.dir}/bin/xjavac.jar"/>
    </classpath>
  </taskdef>

  <!-- Allow properties following these statements to be overridden -->
  <!-- Note that all of these don't have to exist.  They've just been defined
       in case they are used. -->
  <property file="build.properties"/>
  <property file=".ant.properties"/>
  <property file="${user.home}/.ant.properties"/>
  <property file="default.properties"/>
 
  <target name="init">
    <property name='parser.Name' value='Xerces-J'/>
    <property name='parser.name' value='xerces-j'/>
    <property name='parser.shortname' value='xerces'/>
    <property name='parser.Version' value='2.9.1'/>
    <property name='parser.version' value='2.9.1'/>
    <property name='parser_version' value='2_9_1'/>

    <property name='deprecatedjar.parser' value='xerces.jar'/>
    <property name='jar.apis' value='xml-apis.jar'/>
    <property name='jar.parser' value='xercesImpl.jar'/>
    <property name='jar.samples' value='xercesSamples.jar'/>
    <property name='jar.dv' value='xercesDV.jar'/>
    <property name='jar.resolver' value='resolver.jar'/>
    <property name='jar.serializer' value='serializer.jar'/>
    <property name='jar.junit' value='junit.jar'/>

<!-- Lots more properties here... -->

  <!-- =================================================================== -->
  <!-- Prepares the build directory                                        -->
  <!-- =================================================================== -->
  <target name="prepare" depends="init">
    <mkdir dir="${build.dir}"/>
  </target>

  <!-- =================================================================== -->
  <!-- directory creation and file copying common to all configurations    -->
  <!-- =================================================================== -->
  <target name="prepare-common" depends="prepare">
    <!-- create directories -->
    <mkdir dir="${build.src}"/>
    <mkdir dir="${build.dest}"/>
    <mkdir dir="${build.dest}/META-INF"/>
    <mkdir dir="${build.dest}/META-INF/services"/>

    <copy 
      file="${src.dir}/org/apache/xerces/jaxp/javax.xml.parsers.DocumentBuilderFactory"
      tofile="${build.dest}/META-INF/services/javax.xml.parsers.DocumentBuilderFactory"/>

    <copy 
      file="${src.dir}/org/apache/xerces/jaxp/javax.xml.parsers.SAXParserFactory"
      tofile="${build.dest}/META-INF/services/javax.xml.parsers.SAXParserFactory"/>
  	
    <copy 
      file="${src.dir}/org/apache/xerces/jaxp/datatype/javax.xml.datatype.DatatypeFactory"
      tofile="${build.dest}/META-INF/services/javax.xml.datatype.DatatypeFactory"/>
  	
    <copy file=
       "${src.dir}/org/apache/xerces/jaxp/validation/javax.xml.validation.SchemaFactory"
      tofile="${build.dest}/META-INF/services/javax.xml.validation.SchemaFactory"/>

    <copy file="${src.dir}/org/apache/xerces/parsers/org.xml.sax.driver"
      tofile="${build.dest}/META-INF/services/org.xml.sax.driver"/>
    
  </target>

<!-- Lots more targets and tasks here... -->

</project>

Bạn phải chắc chắn rằng bạn đã có tệp xerces-build.xml được lưu trữ ở một nơi dễ dàng truy cập và đồng thời công cụ XPath đã được cài đặt để sẵn sàng sử dụng.


Lựa chọn các thành phần

XPath có một công việc cơ bản chủ yếu là việc thực hiện lựa chọn các nút. Ở phần sau sẽ trình bày nhiều hơn các thao tác về nút nhưng ở phần này chỉ đưa ra ý tưởng để biết được XPath làm thế nào lựa chọn được các nhiệm vụ. Các nhiệm vụ ở đây bao gồm các thành phần, các thuộc tính và dữ liệu gốc — trong tài liệu XML. Tuy nhiên, XPath không phải là API để thực hiện thao tác đánh giá. XPath đạt hiệu quả nhất trong việc khôi phục từng phần của dữ liệu.

Thêm vào đó, các tài liệu XML rất phức tạp và dài. Thậm chí kể cả tài liệu ví dụ cho khóa học này mặc dù đã rất đơn giản nhưng cũng đã gồm hơn 1,400 dòng khác nhau. Bạn có thể lựa chọn ngôn ngữ lập trình phù hợp để có thể thực hiện thao tác thay đổi và xóa dữ liệu khi cần.

Chọn lựa nút gốc

Tất cả các thành phần cơ bản chủ yếu của tài liệu XML — ngoại trừ phần mô tả của tệp XML được đặt ở dòng đầu tiên trong tài liệu bắt đầu bằng từ <?xml— được coi phần tử gốc của tài liệu. Phần tử gốc là phần tử bao quanh toàn bộ tài liệu, chứa trong đó gồm các thành phần, các thuộc tính và các văn bản.

Điều quan trọng phải nhớ rằng phần tử gốc là không khác nhiều so với bất kỳ thành phần nào khác. Nó cũng gồm thuộc tính và chứa các thành phần khác nữa như là dữ liệu mở rộng. Tuy nhiên không có nguyên tắc nào cho việc đặt tên cũng như nội dung chứa trong nút gốc đó. Theo nguyên tắc của XPath việc lựa chọn phần tử gốc cũng giống như việc lựa chọn bất kỳ thành phần nào khác. Chỉ có khác XPath phải xác định điều kiện để bắt đầu tìm kiếm; Nói theo nghĩa khác, phần tử gốc cũng chỉ là một thành phần trong tài liệu luôn luôn biết được chính xác vị trí lưu trữ và mọi lúc nó luôn luôn chứa các thành phần bên trong.

Để chỉ ra rằng công việc tìm kiếm bắt đầu từ phần tử gốc thì XPath của bạn phải bắt đầu với ký tự / (dấu gạch chéo). Ví dụ, nếu bạn có phần tử gốc được đặt tên project, đường dẫn trong Ví dụ 2 lựa chọn thành phần đó.

Ví dụ 2. Lựa chọn phần tử gốc tên project
/project

Không chỉ thực hiện lựa chọn phần tử gốc xác định project, mà còn mô tả hai phần cơ bản của một xác định XPath:

  • Mô tả sự di chuyển và sự kế thừa: Cú pháp có dạng như /hoặc.. để định hướng việc kế thừa trong XML. Hầu hết các cú pháp có dạng tương tự như vậy được sử dụng để định hướng xác định thư mục trong cửa sổ dòng lệnh shell trên Unix hoặc Windows.
  • Các tên của nút: Các tên như "project" hay "name" hay "property" để chỉ tới các thành phần hay các thuộc tính trong tài liệu XML. Các tham chiếu này cho phép chỉ đến một phần của tài liệu ở mức (level) hiện tại từ đó có thể mô tả vị ví bạn đang làm việc của tài liệu

Trong Ví dụ 2, ví dụ đơn giản nhất mô tả sự hoạt động được sử dụng: /. Chỉ dẫn này XPath xác định là bắt đầu từ phần tử gốc của tài liệu. Vì vậy để thực hiện /project, bộ đánh giá XPath bắt đầu công việc tìm kiếm luôn luôn từ phần tử gốc của tài liệu. Vì thế ở mức này công việc thực hiện là tìm kiếm thành phần có tên project.

Để xem hành động này, cố gắng tải tài liệu xerces-build.xml vào công cụ xử lý XPath của bạn và xem /project trong kết quả thu được trong XPath. Bạn sẽ nhìn thấy màn hình có kết quả giống như sau Hình 3.

Hình 3. Định vị phần tử gốc
Start at the root element with the / character

Kết quả này mô phỏng thao tác lựa chọn phần tử gốc của bạn. Tuy nhiên phải chú ý rằng điều đó là chưa đủ để sử dụng chính xác /, mặc dù vậy; bạn cũng cần thiết để có thể lấy được tên của thành phần gốc một cách chính xác.

Có một vài miêu tả sự thay đổi khi đó bạn sẽ phải học về sự tiến triển của bài hướng dẫn này.

Đánh giá XPaths trên Stylus Studio

Stylus Studio là một công cụ thực sự hiệu quả để làm việc. Bởi vì bạn chỉ mất một chút ít thời gian là có thể bắt đầu thực hiện đánh giá xử lý các biểu thức XPath của bạn. Mặc dù không yêu cầu bạn phải làm việc với hết các thành phần của ứng dụng Stylus Studio nhưng để làm việc hiệu quả hơn bạn cũng nên tìm hiểu một chút về các thành phần trong ứng dụng này. Trước tiên hãy bắt đầu với Stylus Studio. Sau đó mở tệp nguồn XML để bắt đầu, trong bài này các bạn sử dụng tệp xerces-build.xml. Tiến theo phía trên của cửa sổ tài liệu — cái phía dưới biểu tượng thoát của toàn bộ ứng dụng sẽ cho phép hiển thị thẻ chứa tên tài liệu của bạn — có một vài biểu tượng. Các biểu tượng này là các ký hiệu không được rõ nghĩa. Các ký hiệu bên phải của dấu "X" được đặt trong phần mũi tên trỏ lên giữa hai thanh ngang màu đen (Open XPath query editor icon). Bấm vào đây, và thêm một khung mới nằm bên phải của tài liệu bạn đang làm. Đây là phần viết câu lệnh truy vấn của XPath, tại đây bạn có thể nhập các câu lệnh XPath của bạn vào. Thực hiện đánh lệnh XPath vào khung thứ hai từ trên xuống và đánh dấu với tên là Query1. Sau đó bạn hãy nhập câu lệnh XPath của bạn vào và bấm vào mũi tên màu xanh (Mũi tên màu xanh trong Stylus Studio) tại phía trên cùng của vùng làm việc XPath để tiến hành đánh giá câu lệnh XPath của ban(Stylus Studio thực hiện xử lý truy vấn của bạn dưới dạng sử dụng XQuery). Các kết quả sẽ xuất hình ở phần khung phía dưới, nhìn vào Hình 4.

Hình 4. Xác định phần tử gốc trong Stylus Studio
Stylus Studio hiển thị các thứ khác nhau dưới dạng sắp xếp ở khung trên của cửa sổ làm việc của bạn

Bắt đầu sử dụng bằng cách mở hai cửa sổ làm việc, một cho tài liệu nguồn (cửa sổ chính) và một cho các kết quả xử lý XPath (tại khung bên phải). Thêm vào đó bạn có thể mở rộng các thành phần làm việc để nhìn thấy các thành phần con và các thuộc tính cũng như các tham số khác của thành phần. AquaPath trên hệ điều hành Mac OS X không hiển thị trực tiếp các thành phần trên giao diện người dùng nhưng nó sẽ hỗ trợ để bạn tìm được kết quả xử lý của bạn.

Chọn lựa các thành phần con chứa bên trong

Như đã biết, việc chọn lựa phần tử gốc được thực hiện một cách nhanh chóng. Tuy nhiên bạn sẽ mất rất nhiều thời gian khi làm việc với các thành phần khác không phải phần tử gốc trong XPath. Để làm việc với các phần tử trong tài liệu bạn bắt buộc phải duyệt qua phần tử gốc.

Giả sử rằng bạn đã có phần tử tên là property là con của phần tử gốc project (project là tên chính xác của phần tử gốc nằm trong tệp xerces-build.xml ví dụ). Bạn đã biết cách làm thế nào để có thể lựa chọn được phần tử gốc cho nên cái bạn cần quan tâm tiếp theo là tên của phần tử con property. Bạn làm việc với XPath dưới dạng như sau Ví dụ 3.

Ví dụ 3. Lựa chọn trực tiếp phần tử property thông qua phần tử gốc
/project/property

Đánh biểu thức trên vào công cụ của bạn và sẽ nhìn thấy kết quả có dạng Hình 5.

Hình 5. Lựa chọn phần tử con
Separate elements with a forward slash

Tham khảo thêm AquaPath nhưng không tập trung vào

Công cụ AquaPath cho hệ điều hành Mac OS X cho phép lựa chọn các thành phần, các thuộc tính và văn bản sau đó để xử lý biểu thức XPath. Các nút được lựa chọn sẽ xuất hiện với màu vàng để phân biệt. Tuy nhiên AquaPath không di chuyển ngay kết quả đến nút đầu tiên hay chỉ hiển thị các nút được lựa chọn. Bạn có thể nhận được nhiều tài liệu tương ứng phù hợp bên trong cửa sổ của AquaPath. Điều này có nghĩa là bạn cũng sẽ nhìn thấy cả các kết quả mà bạn không lựa chọn và khi đó bạn phải cuộn để tìm được kết quả cần chọn lựa. Điều này thực sự là không thuận tiện khi làm việc với hệ điều hành Mac OS X.

Một lần nữa, đường dẫn thư mục tượng trưng lại được đề cập đến. Dấu gạch chéo (/) dùng để phân biệt các phần tử khác nhau và vì thế bạn dùng nó để có thể làm việc với các phần tử ở mức sâu hơn.

Ví dụ 4 là một ví dụ XPath biểu diễn biểu thức phức tạp nhưng rất dễ hiểu.

Ví dụ 4. Lựa chọn phần tử property trực tiếp dựa trên phần tử gốc
/project/taskdef/classpath/pathelement

Hình 6 hiển thị các phần tử được lựa chọn bằng cách thực thi biểu thức XPath trên.

Hình 6. Lựa chọn một số phần tử ở một số mức khác nhau
You can traverse deeply nested hierarchies easily with XPath

Trước khi chuyển sang làm việc với các thuộc tính bạn cố gắng thử làm với một số phần tử con khác bằng XPath trên máy của bạn. Dưới đây là một số ví dụ bạn có thể áp dụng để làm việc với XPaths:

  • Tất cả property của các thành phần con bên trong các phần tử target. target được chỉ rõ dưới phần tử gốc (có tên là project).
  • Tất cả phần tử fileset được đặt trong các phần tử copy. copy được sử dụng như là con của phần tử target, cái được chỉ trực tiếp dưới phần tử gốc.
  • Tất cả các phần tử patternset lồng trong các phần tử unzip. unzip là được lồng trong phần tử target, là phần tử trực tiếp của phần tử gốc.
  • Tất cả các phần tử jar lồng bên trong phần tử target.

Khi bạn làm được các ví dụ XPaths này thì bạn đã sẵn sàng chuyển sang một phần mới đó là tìm kiếm các phần tử bất kỳ trong một tài liệu.


Lựa chọn các phần tử mà không quan tâm đến sự lồng nhau

Vì lý do bạn chỉ có thế tìm đến được vị trí cần xử lý khi bạn bắt đầu đi qua phần tử gốc của tài liệu XML. Nên bạn luôn luôn phải biết chính xác đường dẫn tới các thành phần mà bạn muốn xử lý. Ví dụ đường dẫn XPath kiểu /project/taskdef/classpath/pathelement được sử dụng hiệu quả nếu thỏa mãn hai điều sau:

  1. Bạn biết rằng pathelement là con của classpath, classpath lại là con của taskdef, và taskdef là con của project.
  2. Bạn chỉ muốn pathelement trong bộ xếp lồng riêng biệt, thậm chí nếu classpath là các phần khác nhau của tài liệu XML dưới dạng chứa khác nhau.

Lựa chọn các phần tử khi bạn không có một bộ xếp lồng vào nhau

Bạn sẽ mất nhiều thời gian để có thể xác định được các thành phần trong cấu trúc lồng nhau kể cả khi bạn biết được mô hình ràng buộc của tài liệu. Nhưng nếu bạn muốn có tất cảproperty của các thành phần thì bạn phải xác định được nó được định vị ở vị trí nào? Hoặc nếu bạn muốn xác định mọi thành phần javac nhưng bạn không biết về ràng buộc của tài liệu? Trong trường hợp này bạn cần phải có được cấu trúc thư mục xác định rõ hơn để cho phù hợp.

Sử dụng dấu gạch chéo kép để xác định được vị trí phù hợp của thành phần

Tất cả các biểu thức XPath bạn đã làm trước đó đều bắt đầu với dấu gạch chéo phía trước rồi sau đó đến phần tử gốc. Với cách làm như vậy mặc định hiểu rằng bắt đầu là dấu gạch chéo và ngay sau đó thì phần tử đầu tiên chính là phần tử gốc. Tuy nhiên, bạn có thể sử dụng nhiều hơn một dấu gạch chéo để làm việc với XPath. Xem biểu thức XPath sau Ví dụ 5.

Ví dụ 5. XPath được bắt đầu bằng dấu gạch chéo kép
//property

Biểu thức này trả lại tất cả property các phần tử, mặc dù không có thành phần gì được xuất hiện phía sau. Vì vậy thay vì bắt đầu với phần tử gốc, dấu gạch chéo kép (//) chỉ ra rằng bộ xử lý XPath sẽ tìm kiếm ở bất kỳ vị trí nào trong tài liệu XML. Khi thực hiện xử lý biểu thức này, bộ công cụ của bạn sẽ trả lại property các thành phần nằm trong phần tử gốc, project, cũng tương tự như phần tử target với name giá trị của init (đích đầu tiên gần nhất với phần tử bắt đầu của tài liệu). Bạn có thể xem các kết quả của ví dụ tại trang Hình 7.

Hình 7. Lựa chọn một thành phần bằng cách ẩn đi vị trí xác định
The double slash selects all matching elements regardless of nesting

Tìm kiếm từ bất kỳ vị trí nào trong tài liệu

Bạn đã học hai cách tiếp cận để có được các phần tử thích hợp bằng cách sử dụng XPath:

  • Bắt đầu với phần tử gốc và xác định các vị trí lưu giữ bằng dấu gạch chéo đơn
  • Chỉ dùng tên phần tử cần xác định bằng cách sử dụng dấu gạch chéo kép

Cách tiếp cận này chỉ mới là rất cơ bản nhưng bạn có thể kết hợp hai công nghệ này lại với nhau để có thể làm việc với những yêu cầu phức tạp hơn một cách nhanh chóng. Ví dụ, bạn muốn tìm property các thành phần, nhưng chỉ có được target của các thành phần. Vì thế bạn không muốn property các phần tử nằm trong gốc project element.

Trường hợp này nếu bắt đầu làm việc với phần tử gốc thì không hiệu quả. Trước tiên, bạn xác định không muốn các phần tử đặt lồng trực tiếp vào trong phần tử gốc. Thứ hai, bạn không quan tâm đến vị trí mà property phân tử được đặt vào cũng như nó được đặt vào target. Vì thế rõ ràng bạn muốn sử dụng dấu gạch chéo kép cho một số dạng làm việc vì lúc này hoàn toàn độc lập với việc xác định sự lồng nhau.

Tuy nhiên, bạn muốn chỉ ra một phần tử lồng nhau: cái mà property phải được chỉ rõ được lồng vào property. Ví dụ 6 là thể hiện cái bạn muốn.

Ví dụ 6. Kết hợp dấu gạch chéo kép với sự lồng nhau
//target/property

Theo cách biểu diễn này bạn sẽ nhìn thấy cách làm việc hiệu quả hơn. Trước tiên bạn muốn tất cả target thành phần được đặt ở bất kỳ vị trí nào trong tài liệu. Sau đó //target phân chia của biểu thức XPath cho phép nhận được cái bạn muốn. Tuy nhiên thay vì trả lại các phần tử này bạn muốn tất cả các phần tử property nằm trong đó: //target/property. Vì thế bạn kết hợp phần tử lồng nhau xác định với dấu gạch chéo kép. Thực hiện xử lý biểu thức XPath và bạn sẽ thu được kết quả có dạng như sau Hình 8.

Hình 8. Sử dụng dấu gạch chéo kép với sự lồng nhau
Sử dụng dấu gạch chéo kép với sự lồng nhau

Bạn có thể viết câu lệnh XPath để xác định theo các thành phần sau:

  • Tất cả các phần tử jar ở bất kỳ vị trí nào trong tài liệu XML.
  • Tất cả các phần tử attribute lồng vào trong phần tử manifest cái được lồng vào trong phần tử jar
  • Tất cả các phần tử fileset lồng vào trong các phần tử copy

XPath được xử lý từng phần một

Thỉnh thoảng bạn phải xác định trước cách tiếp cận đánh giá XPath để có thể xử lý các XPath của bạn. Đặc biệt, XPath được xử lý từng phần từng phần một. Trước tiên, bộ xử lý xác định phần đầu của cú pháp, sẽ xảy ra hai trường hợp hoặc là dấu gạch chéo đơn hoặc là dấu gạch chéo kép. Điều này để chỉ ra xem công việc tìm kiếm bắt đầu từ phần tử gốc của tài liệu hay bắt đầu từ một phần tử bất kỳ của tài liệu. Sau đó, bộ xử lý tìm tất cả các phần tử phù với tên của phần tử được đưa ra (giống như phần tử project) luôn luôn được coi là điểm bắt đầu việc xử lý.

Tại thời điểm này, công việc của bạn là định vị được bộ xử lý tới vị trí xác định trong tài liệu. Ví dụ, đối với biểu thức XPath có dạng /project, thì bất kỳ phần tử nào sau phần của biểu thức XPath được xử lý đều phải liên quan tới phần tử hiện tại đang xác định. Đó chính là lý do tại sao bạn có thể định vị được các phần tử được lồng vào: Bộ xử lý luôn luôn đánh giá từng phần của biểu thức và cập nhập vị trí bên trong của tài liệu. Vì vậy biểu thức /project/task/property trước tiên di chuyển tới phần tử gốc, sau đó tới phần tử project , sau đó tới bất kỳ phần tử chứa trong task, và cuối cùng di chuyển tới phần tử property.

Mọi thứ bạn nhận được có thể có một chút ít rắc rối khi bạn thực hiện biểu thức XPath mà lại phù hợp với nhiều phần tử cùng lúc; ví dụ như biểu thức XPath /project/task phù hợp với nhiều thành phầntask được lồng vào trong /project. Thật may mắn, bộ xử lý là đủ thông minh để có lưu giữ từng phần định vị và tiếp tục làm việc nhiều hơn nữa dựa trên các định vị của biểu thức đó.

Điều này tạo nên một sự thú vị, ví dụ biểu thức XPath có dạng như //java/classpath. Trong trường hợp này, bộ xử lý bắt đầu bằng xác định tất cả các thành phần của java ở bất kỳ vị trí nào trong tài liệu — thậm chí tại một mức khác của sự lồng nhau. Đối với từng vị trí trong số các vị trí này, sự lồng nhau của phần tử classpath được xác định để tìm kiếm. Bạn nhận thấy rằng bộ xử lý XPath đang cất giữ nhiều định vị khác nhau.

Từ đó bạn nhận thấy rằng, tư tưởng chính của bộ xử lý luôn luôn làm việc từng phần từng phần một và cập nhật kết quả thu được trong tài liệu và nó là nền tảng mỗi khi bạn bắt đầu để giải quyết cho các xử lý khác trong tài liệu — dưới dạng như là các thuộc tính.


Lựa chọn các thuộc tính

Bất kỳ ai làm việc với XML đều biết rằng thuộc tính là một thành phần quan trọng của xử lý XML. Thực tế các API của XML hoặc các công nghệ thường không xử lý trực tiếp với các thuộc tính và điều này là một hạn chế lớn khi làm việc với tài liệu XML. Trong trường hợp của biểu thức XPath thì kết quả chính của biểu thức thường là lựa chọn các phần của tài liệu XML. Tuy nhiên, các thành phần của tài liệu XML thường được cho dưới dạng sau:

    <property name='deprecatedjar.parser' value='xerces.jar'/>
    <property name='jar.apis' value='xml-apis.jar'/>
    <property name='jar.parser' value='xercesImpl.jar'/>
    <property name='jar.samples' value='xercesSamples.jar'/>
    <property name='jar.dv' value='xercesDV.jar'/>
    <property name='jar.resolver' value='resolver.jar'/>
    <property name='jar.serializer' value='serializer.jar'/>
    <property name='jar.junit' value='junit.jar'/>

Trong đoạn ví dụ này, tất cả các phần tử property đều là phần tử rỗng — còn các từ khác trong ví dụ được gọi là thuộc tính, thuộc tính không chứa phần tử con và không chứa văn bản trong đó. Nếu không hỗ trợ cho phép lựa chọn với thuộc tính của phần tử property, thì tài liệu xml thành ra chỉ có rất ít giá trị trong đó. Và như thế tất nhiên XPath phải cho phép xử lý và làm việc với các thuộc tính.

Lựa chọn thuộc tính

Để biểu thị cho thuộc tính bạn sử dụng thêm vào ở phía trước tên của thuộc tính ký hiệu "at" (@)đó là ký hiệu thường được sử dụng trong các địa chỉ email. Ví dụ nếu bạn muốn tham chiếu đến phần tử có tên là name, bạn sử dụng dạng @name. Như vậy bạn thấy rằng XPath định vị được đầy đủ các phần tử cần xử lý. Nó chỉ rõ tài liệu được đặt ở đâu? Thành phần nào được đặt ở vị trí đó? Và trong các phần tử của XML bất kể phần tử nào cũng đều có các thuộc tính đi kèm có tên là name để thực hiện phân biệt với các phần tử khác?

Áp dụng lại những cái bạn đã biết

Trước khi bạn bắt đầu làm chi tiết bạn phải chắc chắn rằng bạn đã có những hiểu biết cần thiết để có thể làm thế nào lựa chọn được các thuộc tính. Hay tham khảo thêm tại Ví dụ 7, và có thể dự đoán liệu XPath thực hiện lựa chọn cái gì tương ứng.

Ví dụ 7. Các thuộc tính nào được lựa chọn?
//@name

Bạn đã biết rằng dấu gạch chéo kép nói rằng bộ định vị tiến hành tìm kiếm ở bất kỳ một vị trí nào trong tài liệu XML. Bạn cũng biết rằng @name thực hiện lựa chọn các thuộc tính có tên là name. Vì thế Ví dụ 7 thực hiện lựa chọn tất cả các thuộc tính có tên là name ở mọi vị trí của tài liệu XML (ở đây không quan tâm tên của thành phần mà thuộc tính đó xuất hiện bên trong).

Xác định phần tử có chứa thuộc tính trong đó

Bạn đã nhìn thấy biểu thức XPath có dạng project/property thì ban đầu thực hiện lựa chọn phần tử project, sau đó lựa chọn phần tử property được chứa bên trong. Dấu gạch chéo đơn được sử dụng để phân biệt các phần của được dẫn. Cũng ví dụ như vậy, Biểu thức XPath sau property/@name trước tiên tiến hành lựa chọn phần tử có tên là property, sau đó lựa chọn thuộc tính có tên là name trên chính phần tử đó. Ghép tất cả các phần này lại với nhau bạn có thể nhận được kết quả có dạng như Ví dụ 8.

Ví dụ 8. Lựa chọn thuộc tính dựa trên một đường dẫn đầy đủ
/project/property/@name

Hình 9 Hiển thị các kết của việc xử lý XPath trong AquaPath.

Hình 9. Lựa chọn các thuộc tính name của thuộc tính property
The @ sign indicates an attribute

Kết hợp dấu gạch chéo kép với việc tìm kiếm các thuộc tính

Khi bạn sử dụng dấu gạch chéo kép để mở rộng việc tìm kiếm với các phần tử thì bạn có thể làm việc cùng lúc với nhiều phần tử. Ví dụ như bạn muốn tìm kiếm thuộc tính allname trên tất cả các phần tử property, ở đây không quan tâm phần tử property có được chứa trong phần tử gốc không (project). Bạn sử dụng biểu thức XPath có dạng như trong Ví dụ 9.

Ví dụ 9. Mở rộng việc tìm kiếm với các thuộc tính name
//property/@name

Biểu thức XPath này giống như trong Ví dụ 8, dùng để tìm kiếm các thuộc tính name trên các phần tử có tên là property, nhưng lúc này phần tử property có thể xuất hiện ở bất kỳ vị trí nào trong tài liệu. Hình 10 hiển thị kết quả của việc tìm kiếm có ít ràng buộc hơn.

Hình 10. Tìm kiếm tất cả các thuộc tính property/@name
A double slash is less restrictive than a single slash

Lựa chọn giá trị của thuộc tính

Trong trường hợp làm việc với các phần tử, kết quả thu được của lệnh lựa chọn luôn là thành phần và thuộc tính của phần tử được lựa chọn. Nhưng có lúc, bạn sẽ muốn có giá trị của thuộc tính được lựa chọn. Trước tiên, bạn nên chỉ ra cách sắp xếp giá trị ngay từ ban đầu để làm giảm sự khác biệt giữa XPath (xác định các thành phần được lựa chọn) và XQuery(cho phép xây dựng biểu thức XPath thực hiện nhiều xử lý và truy vấn phức tạp, đồng thời trả lại các giá trị dưới dạng các phần tử và các thuộc tính).

Thêm vào đó, các công cụ bắt đầu phải có nhiều sự thay đổi để bạn có thể làm việc với nhiều nguyên tắc hơn. Tuy nhiên, bạn có thể trả lại giá trị gốc của thuộc tính khi thực hiện lời gọi hàm string(). Ví dụ 10 thể hiện cách mà bạn thực hiện xử lý biểu thức XPath của bạn.

Ví dụ 10. Nhận giá trị gốc của thuộc tính
string(/project/@default)

Thử thực hiện điều này trong công cụ AquaPath. Bạn sẽ lựa chọn thẻ String-value để chuyển đổi từ việc lựa chọn các phần khác nhau của tài liệu sang việc lựa chọn giá trị, đó là kết quả của lời gọi hàm string(). Các kết quả như trong Hình 11.

Hình 11. Sử dụng hàm string() trong AquaPath
string() trả lại giá trị gốc của thuộc tính

Hình 12 hiện thị các kết quả tượng tự trong Stylus Studio.

Hình 12. Sử dụng hàm string() trong Stylus Studio
string() is an XPath function for returning string values

Hàm string() làm việc trên từng thuộc tính riêng rẽ

Vấn đề lớn nhất là mọi người nhanh chóng chạy hàm string() trong khi họ cố gắng sử dụng nó dưới dạng tập giá trị. Ví dụ, xem biểu thức XPath đầu tiên trong Ví dụ 9: //property/@name. Trong ví dụ tài liệu tương tự, biểu thức XPath trả lại một số thuộc tính thay vì chỉ trả lại một kết quả. Vì thế thử áp dụng hàm string() cho biểu thức này — theo dạng sau: string(//property/@name)— phát sinh ra lỗi. Đó là bởi vì hàm string() nhận thuộc tính đơn như là đối số.

Vì lý do này, nếu bạn không chắc chắn vào kết quả, các hàm như hàm string() là cách tốt nhất để cho các thuộc tính giá trị đơn giống như thuộc tính trên phần tử gốc của tài liệu. Theo quy ước mỗi một tài liệu chỉ có duy nhất một phần tử gốc vì thế bạn không phải lo lắng trường hợp có khả năng trả lại nhiều giá trị. Đó là lý do tại sao biểu thức XPath trong Ví dụ 10 làm việc được.

Nếu bạn muốn thực hiện xử lý để có giá trị của nhiều phần tử hay nhiều thuộc tính, bạn phải tìm hiểu thêm lĩnh vực XQuery ở các liên kết của phần Tài nguyên). Ngay bây giờ, tập trung vào việc lựa chọn các phần tử hoặc các thuộc tính (hay văn bản), và quan tâm đến các giá trị khi xây dựng sẽ thu được ở phần sau.


Mở rộng kết quả bằng sử dụng ký tự thay thế và toán tử |

Bạn đã thực hiện lựa chọn các phần tử và các thuộc tính bằng cách sử dụng dấu nháy kép, từ đó bạn có thể tìm kiếm các phần tử và các thuộc tính này ở bất kỳ vị trí nào của tài liệu. Tuy nhiên bạn vẫn bị giới hạn do đặc trưng của XPath đó là bạn cần phải biết được tên của các phần tử và các thuộc tính mà bạn muốn tìm kiếm.

Nhưng các giới hạn này giả định rằng bạn biết chính xác cái bạn cần tìm kiếm thậm chí không bị hạn chế bởi trong đó các thành phần và các thuộc tính được chỉ rõ. Để chuyển biểu thức XPath của bạn sang xử lý ở mức khác bạn cần thêm vào các ký hiệu đại diện cho hộp công cụ, cách tốt nhất là kết hợp hai biểu thức XPath để có được hợp của các kết quả.

Sử dụng ký tự thay thế để lựa chọn tất cả các nút

Trong hầu hết các hệ thống xử lý và chương trình đều sử dụng ký tự thay thế là * (dấu hoa thị) để thay thế cho một vài ký tự. Với XPath ký tự thay thế * có nghĩa là thay thế cho tất cả. Ví dụ, ký tự thay thế * được thay thế cho tất cả các phần tử tại bất kỳ vị trí nào của tài liệu hoặc tất cả các thuộc tính — nhưng không thể đồng thời cả hai.

Lựa chọn tất cả các thuộc tính của các phần tử

Quay lại xem biểu thức XPath của Ví dụ 9: //property/@name. Ví dụ này có nghĩa rằng bạn muốn tìm tất cả các phần tử của property và trả lại các thuộc tính của phần tử đó mà không quan tâm đến tên của thuộc tính. Có thể bạn không biết rằng name là một thuộc tính hoặc là bạn muốn đề cập đến tất cả các thuộc tính (kể cả giá trị của nó). Trong trường hợp này bạn có thể thay thế thuộc tính tên (name) bằng ký tự thay thế, giống như trong Ví dụ 11.

Ví dụ 11. Sử dụng ký tự thay thế để lựa chọn tất cả các thuộc tính trên một phần tử
//property/@*

Thực hiện xử lý XPath trên máy của bạn và bạn sẽ thấy kết quả như Hình 13.

Hình 13. Khôi phục tất cả các thuộc tính trong một phần tử
The * character replaces all possible attribute names

Mấu chốt vấn đề ở đây là liên quan đến dấu hoa thị (*) đơn giản được dùng để thay thế cho tên của thuộc tính. Vì thế biểu thức XPath trong Ví dụ 11 sẽ lấy được nhiều giá trị khác nhau. Trong trường hợp bạn sử dụng dạng như //property/@name, //property/@value, //property/@file cũng cho kết quả dạng tương tự. Trong mỗi trường hợp, dấu hoa thị (*)> được đại diện cho tên của từng thuộc tính riêng lẻ.

Sử dụng ký tự thay thể để lựa chọn tất cả các phần tử con

Trong trường hợp này, bạn sử dụng các ký tự thay thế để tìm ra tất cả các phần tử con của từng phần tử được xử lý. Xem biểu thức XPath //target/copy/fileset. Từ đó bạn có thể mở rộng biểu thức XPath dưới dạng như Ví dụ 12.

Ví dụ 12. Sử dụng ký tự đại diện để lựa chọn tất cả các phần tử con của phần tử
//target/copy/*

Cách lựa chọn này lựa chọn tất cả các phần tử con buộc bên trong //target/copy. Vì thế kết quả là phần tử fileset hoặc là path của phần tử sẽ được tiếp cận đến. Kết quả của biểu thức này khi thực hiện có thể khác nhau dựa trên tài liệu nguồn, nhưng Hình 14 hiển thị phân loại của tập hợp kết quả dựa trên tài liệu ví dụ mà bạn đã đang sử dụng

Hình 14. Khôi phục tất cả các phần tử con của phần tử
The * character can represent elements, too

Một ký tự đại diện luôn luôn thay thế cho một cái gì đó

Điều quan trọng là phải xác định được ký tự đại diện được dùng để thay thế cho cái gì trong tài liệu nguồn. Điều này rất quan trọng mặc dù việc làm này có vẻ mơ hồ và không sáng sủa khi thực hiện. Ví dụ tìm hiểu đoạn mã XML sau:

 <copy file=
       "${src.dir}/org/apache/xerces/jaxp/javax.xml.parsers.DocumentBuilderFactory"
      tofile=
       "${build.dest}/META-INF/services/javax.xml.parsers.DocumentBuilderFactory"/>

    <copy file=
       "${src.dir}/org/apache/xerces/jaxp/javax.xml.parsers.SAXParserFactory"
      tofile=
       "${build.dest}/META-INF/services/javax.xml.parsers.SAXParserFactory"/>

Cả hai thẻ thành phần copy trên đều không chứa phần từ con trong nó. Vì thế không phải các giá trị này sẽ được trả lại khi thực hiện biểu thức XPath trong Ví dụ 12, //target/copy/*. Thậm chí ngay trong phần đầu của biểu thức XPath đã chỉ rõ dấu * thay thế cho phần tử bất kỳ nhưng sẽ không có phần tử nào hiển thị trong kết quả

Khi bạn sử dụng toán tử thay thế — trên các phần tử hoặc trên các thuộc tính — thì phải mô tả rõ ký tự thay thế phải thay thế cho những cái gì. Sự không có giá trị là không sử dụng để thay cho ký tự đại diện.

Ký tự đại diện luôn luôn miêu tả chỉ một thứ

Trong trường hợp này ký tự thay thế miêu tả một số thứ trong một số trường hợp ký tự thay thế cũng miêu tả chỉ cho một thứ. Trong các trường hợp khác, ký tự thay thế trong biểu thức //target/copy/* thay thế chỉ cho một mức con nằm trong của phần tử copy. Vì thế nếu có hai mức con được hiển thị trong phân tử copy— có lẽ cần phần tử fileset chứa các phần tử path bên trong vì thế — có thể bạn chỉ có thể nhận được các mức con của mức đỉnh.

Có một vấn đề bạn cần quan tâm đó bạn có thể sử dụng ký tự thay thế ở phần giữa của biểu thức XPath. Ví dụ 13 hiển thị kết quả của ví dụ sử dụng ký tự thay thế được đặt ở phần giữa của biểu thức XPath.

Ví dụ 13. Sử dụng ký tự thay thế trong phần giữa của biểu thức XPath
//target/*/@name

Ví dụ này là có thể thực hiện được bởi vì trong biểu thức XPath cho phép xử lý theo từng phần một. Trước tiên bộ xử lý tìm tất cả thành phần target dấu nháy kép chỉ rằng có thể tiến hành tìm kiếm từ bất kỳ vị trí nào trong tài liệu XML. Tiếp theo ký tự thay thế * chỉ định bộ xử lý thực hiện tìm tất cả các thành phần con của target. Mặc dù không chỉ định rõ tên thành phần cần tìm nhưng bất kỳ thành phần nào chứa trong target đều được truy cập tới. Sau đó, đến dấu gạch chéo đơn (/) để phân biệt ký tự thay thế từ các phần khác của biểu thức. Biểu thức XPath được xây dựng dựa vào các định vị vị trí vì thấy bộ xử lý nhóm các thành phần con của target như là vị trí hiện tại.

Sau đó, bộ xử lý áp dụng từng phần biểu thức XPath @name. Biểu thức này cho phép lựa chọn tất cả các thuộc tính có tên là name từ tập hợp thành phần hiện tại. Vì thế các phần tử có tên là property hoặc taskdef hoặc bất kỳ phần tử nào mà có thuộc tính tên là name đều trả lại các thuộc tính tương ứng phù hợp.

Trường hợp như trên là một trong các cách hiệu quả để làm việc với XPath và các ký hiệu thay thế. Để thay thế cho việc tìm kiếm tất cả các thuộc tính của thành phần hay tất cả các con của phần tử bạn có thể muốn — từng thuộc tính hoặc từng phần tử con — mà không quan tâm tới đường dẫn được sử dụng để đến được các thuộc tính hoặc các con này. Khi đó bạn thậm chí có thể sử dụng nhiều hơn hai ký hiệu thay thế, xem tại Ví dụ 14.

Ví dụ 14. Sử dụng nhiều ký hiệu thay thế trong một biểu thức XPath.
//target/*/*/@includes

Hình 15 hiển thị các kết quả từ biểu thức XPath; trong đường dẫn của ví dụ này thuộc tính includes là rất khác nhau trong mỗi trường hợp nhưng trong cùng một mức là giống nhau vì thế đích cơ bản là: tên của thuộc tính includes hai mức con của phần tử target.

Hình 15. Sử dụng hai ký hiệu thay thế trong một biểu thức XPath đơn
Mỗi dấu * thay thế cho một phần tử (element)

Kết hợp biểu thức XPath lựa chọn

Ký hiệu thay thế cho phép bạn thay thế một ký tự cho từng phần của biểu thức XPath. Tuy nhiên thỉnh thoảng bạn muốn tất cả các thành phần này, và trong tất cả các thành phần kia. Theo một cách khác, bạn muốn kế hợp kết quả của hai biểu thức XPath. Khi đó bạn sử dụng ký tự OR để kết hợp, ký tự này được biểu diễn bằng dấu thẳng đứng: |.

Hãy sử thử một ví dụ đơn giản bằng cách sử dụng ký hiệu OR để kết hợp hai biểu thức XPaths và xem kết quả như là một biểu thức XPath mới. Ví dụ 15 trình bày một ví dụ đơn giản.

Ví dụ 15. Kết hợp hai biểu thức XPath
/project/property | /project/task/property

Trong trường hợp này, hai vị khác nhau được kết hợp lại thành một tập kết quả. Tất cả các phần tử property của phần tử gốc được trả lại đồng thời tất cả các phần tử property thuộc phần tử task nằm trong mức phần tử gốc. Chức năng này là hoàn toàn khác so với các biểu thức XPath bạn đã làm trước đó, //property, bởi vì nếu phần tử property có một số phần tử lồng nhau ở sâu hơn hoặc các phần tử không nằm trong phần tử task hay phần tử gốc thì nó không trả kết quả khi thực hiện biểu thức XPath Ví dụ 15. (Đây là sự chú giải cần thiết trong khi cách viết //property là khác so với biểu thức XPath trong Ví dụ 15tập hợp kết quả là giống nhau trong tài liệu XML ví dụ vì thế đó là tập hợp các phần tử giống nhau được sử dụng.)

Lựa chọn các phần tử và các thuộc tính khác loại

Sẽ thú vị hơn nhiều khi kết hợp để mở rộng từ lựa chọn đơn giản phần tử giống nhau ở các vị trí khác nhau để cho phép lựa chọn các phần tử khác nhau. Ví dụ tìm hiểu biểu thức XPath trong Ví dụ 16.

Ví dụ 16. Kết hợp nhiều biểu thức XPath
//copy/@file | //copy/fileset

Hình 16 hiển thị kết quả của việc xử lý biểu thức XPath trong ví dụ 16.

Ví dụ16. Tìm kiếm hai biểu thức XPath cùng lúc
Các kết quả của từng XPath được kết hợp với nhau

Sự kết hợp này tiến hành tìm kiếm các thuộc tính file trên các phần tử copy với các phần tử con của phần tử copy được đặt tên là fileset. Nó sẽ lấy tất cả các tệp mà có thể được sao chép cho dù chúng được biểu diễn thế nào trong tệp đó.

Tất nhiên, bạn có thể có làm việc với các biểu thức phức tạp hơn như bạn muốn. Bạn vừa sử dụng ký tự thay thế và đồng thời sử dụng kết nối nhiều biểu thức XPath lại với nhau. Ví dụ 17 chứa một số ý tưởng để bạn làm thử. Những biểu thức XPath này gợi ý cách sử dụng ký tự thay thế và toán tử kết nối.

Ví dụ 17. Ví dụ một số biểu thức XPath sử dụng các ký tự thay thế và toán tử kết nối
//target/@name | //target/@depends
//copy/@todir | //copy/fileset/@dir
//gzip/@zipfile | //tar/@tarfile | //delete/@file
//target/*/@dir | //target/*/fileset

AND hay OR?

Trước khi bạn kết thúc với các ký tự thay thế và toán tử kết nối (|) bạn phải nhớ một quy tắc: Tên của toán tử kết nối là có chút khó hiểu. Trong nhiều trường hợp bạn sẽ tham chiếu nó như nghĩa là OR mặc dù nó xuất hiện nhiều trong ngữ nghĩa của các ngôn ngữ lập trình. OR thường áp dụng cho các biểu thức logic để xác định điều kiện hoặc cái này hoặc cái kia đúng. Ý nghĩa này cũng được mô tả tương tự như thế khi làm việc trong biểu thức XPath nhưng tất nhiên không phải hoàn toàn lúc nào cũng đúng như thế.

Bạn cũng sẽ gặp ký hiệu được gọi là AND để chỉ rằng "tất cả các kết quả trong biểu thức XPath này và tất cả các kết quả trong XPath kia". Thông thường, AND được sử dụng để chỉ rằng cả hai mệnh đề phải đúng; tuy nhiên trong trường hợp sử dụng ký hiệu (|), bạn muốn nói rằng hoặc XPath được áp dụng hoặc bao gồm nút phù hợp tương ứng.

Sử dụng ký hiệu chỉ dẫn trong biểu thức Xpath thực tế là tập hợp toán tử nhưng không phải là AND hay OR. Các kết quả của biểu thức thứ nhất kết hợp với các kết quả của biểu thức thứ hai. Nếu cho rằng XPath thực sự trả lại tập hợp các phần tử hay các thuộc tính (hay văn bản) thì bạn kết hợp chúng lại thành tập hợp. Đấy là xử hợp thậm chí bạn ít khi thấy tài liệu XPath tham chiếu tới các tập hợp. Tuy nhiên cách tốt nhất để giải quyết vấn đề sử dụng dấu thẳng đứng (|) hơn là bắt đầu làm với AND và OR.


Cái nào chính xác là các nút?

Phần tiếp theo bạn sẽ đi nghiên cứu về một định nghĩa chính xác: node (nút). Trong quá trình bạn làm việc với các biểu thức XPath ở phần trên chắc chắn bạn đã có một chút hiểu biết về các nút khi bạn làm việc với XPath từ các ví dụ đơn giản đến các ví dụ phức tạp.

Các nút đều có một đặc điểm chung

Theo định nghĩa đơn giản, nút là một kiểu dữ liệu chưa rõ ràng dùng để xác định cho XPath và API dưới dạng DOM. Nếu bạn làm việc với Java, C# hay các ngôn ngữ lập trình hướng đối tượng khác, nút hơi giống như giao diện hay lớp trừu tượng. Tất cả các kiểu được xây dựng bởi XML mà bạn đã lựa chọn như — các phần tử, các thuộc tính và văn bản — đều được coi là các nút. Vì thế có các nút phần tử, các nút thuộc tính và các nút văn bản. (Chính xác có thể có nhiều loại nút hơn nhưng ở đây chỉ đề cập đến ba loại cơ bản bạn cần biết để làm việc với XPath hiệu quả hơn.)

Do tồn tại khái niệm các nút nên công cụ xử lý XPath có một số kiểu dữ liệu cơ bản để làm việc với tất cả các biểu thức XPath. Điều mà ta cần quan tâm đó là biểu thức XPath dù trả lại các phần tử hay trả lại các thuộc tính thì kết quả cuối cùng tất cả các biểu thức XPath đều trả lại các nút. Trong hầu hết các trường hợp các nút trả lại là cùng kiểu với nhau. Nhưng khi bạn kết hợp các biểu thức XPath với nhau bạn phải có các thuộc tính và các phần tử trả lại tương ứng với biểu thức kết hợp XPath đó. Như vậy cuối cùng thì một biểu thức XPath sẽ trả lại các nút.

Tất nhiên khi bạn làm việc với các tài liệu XML của các tác giả khác nhau và của người lập trình khác nhau thì bạn gặp vấn đề khó khăn khi xử lý với các phần tử và các thuộc tính. Vấn đề này được giải quyết khi mà biểu thức XPath trả lại các nút thay vì các phần tử và các thuộc tính. Vì thế mà cả hai đối tượng Dog hay Cat đều được kế thừa từ lớp cơ bản Animal, các phần tử và các thuộc tính đều là các nút cơ bản.

XPath quan tâm đến tập hợp các nút

Không chỉ khi thực hiện các XPath mới trả lại các nút mà còn có thể trả lại một tập hợp các nút. Trong đại số tuyến tính tập hợp được định nghĩa như một bộ sưu tập các phần tử cùng loại. Ngoài ra, tập hợp có thể là tập rỗng, có một phần tử hoặc có nhiều hơn hai phần tử. Vì thế trong lĩnh vực của XPath thì một biểu thức XPath cũng có thể trả lại một nút rỗng, một nút đơn hay nhiều hơn một nút. Ví dụ biểu thức XPath //target trả lại 39 nút tất cả khi thực hiện với ví dụ; biểu thức XPath //gzip/@zipfile | //tar/@tarfile | //delete/@file trả lại 14.

Dựa trên ý tưởng của tập hợp nút — và thực tế tập hợp nút có thể không có thành phần bên trong — nên cần phải phân biệt sự khác nhau giữa biểu thức XPath không hợp lệ và biểu biểu thức hợp lệ nhưng không có giá trị. Ví dụ, biểu thức XPath không hợp lệ là có xảy ra lỗi cú pháp tức là biểu thức xây dựng không đúng luật hoặc dùng sai mực đích, giống như //gzip/@zipfile || //tar/@tarfile. Trong ví dụ này đã dùng hai dấu thẳng đứng thay vi chỉ được sử dụng một ký hiệu điều này dẫn đến tạo cho biểu thức XPath là không hợp lệ. Các công cụ như AquaPath và Stylus Studio sẽ thông báo đây là lỗi hoặc biểu thức không hợp lệ. Mặt khác, biểu thức XPath //target/*/*/*/@dir là hợp lệ nhưng không trả lại nút nào (tập hợp nút rỗng nhưng dù sao vẫn trả lại một tập hợp nút).

Khi bạn bắt đầu nghĩ đến vấn đề mỗi biểu thức XPath sẽ trả lại một tập hợp các nút, toán tử thẳng đứng (|) tạo ra sự linh hoạt sử dụng. Mỗi khi biểu thức XPath được xử lý nhiều tập hợp các nút được trả lại vì thế các tập hợp này được kết hợp lại với nhau thành một tập hợp nút lớn hơn. Tập hợp các nút cuối cùng có thể là không giống nhau vì tập hợp đó có thể là các phần tử, các thuộc tính và thậm chí là văn bản.

Đứng từ phương diện về mặt cú pháp, các nút được hiểu là sẽ không làm thay đổi cách bạn viết các biểu thức XPath. Tuy nhiên, các nút cũng sẽ làm thay đổi cách bạn suy nghĩ về chúng. Từ đó giúp bạn phân biệt giữa tập hợp nút rỗng — từ biểu thức XPath hợp lệ — và lỗi xảy ra với biểu thức XPath không hợp lệ.


Kết luận

Trong phần 1 của bài hướng dẫn XPath này bạn bạn đã bắt đầu làm quen với việc sử dụng XPath và bạn cũng thực sự hiểu về các hoạt động cơ bản cũng như tập hợp của các toán tử. Đồng thời bạn cũng sẽ biết về một số điểm chính của XPath.

Các điểm nhấn

XPath là vấn đề được lựa chọn đầu tiên. XSL và XSLT, XQuery và API giống như Java API cho xử lý XML và TrAX cho java đều được xây dựng dựa trên XPath. Tuy nhiên, XPath luôn luôn dùng để lựa chọn một thứ (hoặc nhiều thứ). Tiếp sau đó bạn sử dụng — tác giả tài liệu, tác giả của ứng dụng hoặc trình xử lý XML — để làm việc với lựa chọn này. Mặc dù bạn không mong chờ XPath thực hiện tính toán hoặc thực hiện trên danh sách lặp đi lặp lại các tính toán trên các thuộc tính của bạn thì cách tốt nhất là bạn nên bắt đầu làm thử.

Tiếp theo, XPath là đặc tả dựa trên nút. Xpath không nghĩ về các điều khoản của các phần từ và các thuộc tính mà hơn thế XPath quan tâm đến các nút (là các nút cơ bản). Khi bạn đến với XPath bạn sẽ trả lại tập hợp các nút: rỗng, một hoặc nhiều hơn. Thông thường bạn sẽ làm việc với tập các nút cùng kiểu với nhau nhưng XPath vẫn quan tâm đến các thứ khác liên quan trong tập các nút đó.

Cuối cùng bạn phải nhớ rằng XPath được xử lý theo từng phần từng phần một. Đầu tiên là dấu gạch chéo đơn hoặc dấu gạch chéo kép để phân biệt các phần với nhau sau đó đến các phần tử hay ký tự đại diện. Ký tự đại diện toàn bộ (*s) được dùng để thay cho một phần của biểu thức Path và bạn cần làm thử trực tiếp các ví dụ để đánh giá biểu thức XPath.

Lưu ý rằng cú pháp của ba điểm nhấn quan trọng này giống với ngôn ngữ tự nhiên. Cú pháp, một cách cơ bản, chỉ là một lệnh tìm kiếm Google, một tham chiếu đến sách, hoặc một bài viết trên developerWorks. Các khái niệm liên quan sẽ giúp bạn hiểu rõ hơn là học vẹt.

Vấn đề tiếp theo là gì?

Một bài hướng dẫn khác trong loạt bài này

Trong phần 2 của bài hướng dẫn này bạn sẽ tiếp cận tới việc lựa chọn dựa vào các tên, vị trí và quan hệ giữa các phần tử với nhau. Bạn sẽ học về các tính chất, thuộc tính và làm thế nào để lựa chọn các công việc hoàn toàn mới. Với các thuộc tính và tính chất đã có bạn có thể thêm vào các điều kiện để phù hợp với yêu cầu xử lý của bạn. Mục đích bạn muốn chỉ là các phần tử target với tên của init, hoặc bạn chỉ muốn các phần tử property mà có thuộc tính value và là các con của phần tử gốc. Mấu chốt vấn đề để tăng thêm độ phức tạp cho các biểu thức XPath có tính chất phù hợp.

Trong khi bạn đã sẵn sàng để chuyển sang xử lý với phần 2 bạn hãy quay lại sử dụng các công cụ đánh giá XPath của ban. AquaPath và Stylus Studio là hai công cụ tốt nhất để đánh giá các biểu thức XPath và chỉ rõ làm thế nào các xử lý này thực hiện. Giao diện cũng được tạo ra sao cho có thể quay lại một cách dễ dàng để tham chiếu trước khi bạn di chuyển đến các tính chất.


Tải về

Mô tảTênKích thước
Mã nguồn ví dụxpath-2_exampleXml.zip57KB

Tài nguyên

Học tập

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

  • Stylus Studio 2008 XML: Tải về để bắt đầu với các tài liệu về XPath và XML trên nền hệ điều hành Window
  • AquaPath: Tải về để làm việc dễ dàng với XPath trên nền hệ điều hành Mac OS X.
  • Phần mềm Scandalous: Kiểm tra tập hợp các công cụ liên quan của XML dựa trên nền hệ điều hành Mac OS X
  • Java & XML, Xuất bản lần thứ 3 (Brett McLaughlin và Justin Edelson, Công ty truyền thông O'Reilly, 2006): Toàn bộ phần XML từ đầu đến cuối đều bao gồm một lượng lớn các từ vựng liên quan đến XML.
  • Phần mềm dùng thử IBM cho việc đánh giá sản phẩm: Xây dựng dự án tiếp theo của bạn với phần mềm dùng thử bằng cách tải trực tiếp từ Đội phát triển, phần mềm bao gồm các công cụ phát triển ứng dụng và các sản phẩm middleware từ DB2®, Lotus®, Rational®, Tivoli®, và WebSphere®.

Thảo luận

Bình luận

developerWorks: Đăng nhập

Các trường được đánh dấu hoa thị là bắt buộc (*).


Bạn cần một ID của IBM?
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.

 


Ở lần bạn đăng nhập đầu tiên vào trang developerWorks, một hồ sơ cá nhân của bạn được tạo ra. Thông tin trong bản hồ sơ này (tên bạn, nước/vùng lãnh thổ, và tên cơ quan) sẽ được trưng ra cho mọi người và sẽ đi cùng các nội dung mà bạn đăng, trừ khi bạn chọn việc ẩn tên cơ quan của bạn. Bạn có thể cập nhật tài khoản trên trang IBM bất cứ khi nào.

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

Chọn tên hiển thị của bạn



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.

Các trường được đánh dấu hoa thị là bắt buộc (*).

(Tên hiển thị cần có từ 3 đến 30 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.

 


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


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=70
Zone=Công nghệ Java, Nguồn mở
ArticleID=387528
ArticleTitle=Định vị các phần dữ liệu cụ thể của tài liệu XML với XPath, Phần 1
publish-date=05202009