« | October 2025 | » | 日 | 一 | 二 | 三 | 四 | 五 | 六 | | | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | | |
| 公告 |
用一句流行话说,我是外行,我怕谁!
嘿嘿!其实嘛,我是说,我什么都不懂,说错了你别见怪!
|
Blog信息 |
blog名称:X'Me, Love 日志总数:20 评论数量:40 留言数量:0 访问次数:153255 建立时间:2008年8月8日 |

| |
[xmlStudy]UnderstandingXPath01 文章收藏
半路和尚 发表于 2008/10/9 0:43:01 |
So far, this lesson has been all theory. You need this theory as a foundation for practical application, which is what the rest of this lesson is all about.
XSLT wouldn't work if it didn't have some kind of mechanism to match and select nodes and act on them. You need to be able to express which node or nodes should match. This is what XPath expressions are for. XPath is the language you use to specify which node or nodes you want to work with. Expressions in XPath can be very simple, pointing to a specific location within a document tree using absolute addressing. You can, however, make selections based on very complex rules. As you work your way through this book, you will learn to create more and more complex expressions. But, of course, you need to start simple.
Selecting Elements
If you're familiar with addresses on the World Wide Web, the most basic XPath expressions are easy to understand. A Web site is a hierarchy of files, just like an XML document is a hierarchy of elements. If you visit a Web site, you specify its root with the name of the Web site. For example, http://www.somesite.com points to the root or home page of the Web site. This is the same as http://www.somesite.com/, which is actually more accurate. What comes after this part of the address specifies where in the hierarchy of the site you want to be. So, http://www.somesite.com/menu/entrees points to the index file in the entrees directory, which is a child of the menu directory, which is a child of the root directory. The /menu/entrees path is especially interesting. It uniquely identifies a location within the Web site hierarchy, as shown in Figure 3.4.
Figure 3.4 Web site hierarchy.
Figure 3.4 shows part of the hierarchy for the Web site. Notice that /menu/entrees uniquely identifies the entrees node in the tree. If you want to select the desserts node, you change to /menu/desserts. Now look at Listing 3.1.
Listing 3.1 Menu in XML Corresponding to Figure 3.4
1: <?xml version="1.0" encoding="UTF-8"?>
2: <menu>
3: <appetizers title="Work up an Appetite">
4: <dish id="1" price="8.95">Crab Cakes</dish>
5: <dish id="2" price="9.95">Jumbo Prawns</dish>
6: <dish id="3" price="10.95">Smoked Salmon and Avocado Quesadilla</dish>
7: <dish id="4" price="6.95">Caesar Salad</dish>
8: </appetizers>
9: <entrees title="Chow Time!">
10: <dish id="5" price="19.95">Grilled Salmon</dish>
11: <dish id="6" price="17.95">Seafood Pasta</dish>
12: <dish id="7" price="16.95">Linguini al Pesto</dish>
13: <dish id="8" price="18.95">Rack of Lamb</dish>
14: <dish id="9" price="16.95">Ribs and Wings</dish>
15: </entrees>
16: <desserts title="To Top It Off">
17: <dish id="10" price="6.95">Dame Blanche</dish>
18: <dish id="11" price="5.95">Chocolat Mousse</dish>
19: <dish id="12" price="6.95">Banana Split</dish>
20: </desserts>
21: </menu>
NOTE
You can download the sample listings in this lesson from the publisher's Web site.
The XML in Listing 3.1 has the same tree structure as that of the Web site depicted in Figure 3.4. So, just like in the Web site, /menu/entrees points to the entrees element in the XML document. Pointing to a certain node in an XML document with XPath is, as you can see, very simple. It is based on principles that you have probably used before, so they'll be familiar to you, even though you've never worked with XPath before. To see how this approach really works, look at Listing 3.2.
Listing 3.2 Stylesheet Selecting the entrees Node from Listing 3.1
1: <?xml version="1.0" encoding="UTF-8"?>
2: <xsl:stylesheet version="1.0"
3: xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
4:
5: <xsl:template match="/">
6: <xsl:value-of select="/menu/entrees" />
7: </xsl:template>
8:
9: </xsl:stylesheet>
The template on line 5 matches the root element of the source document. The value retrieved on line 6 is selected using the expression /menu/entrees, which matched the entrees element that is the child element of the root element menu. The result from applying Listing 3.2 to Listing 3.1 is shown in Listing 3.3.
注:第5行匹配根元素。第6行利用表达式/menu/entrees检索到的是与根元素menu的子元素entrees。
Listing 3.3 Result from Applying Listing 3.2 to Listing 3.1
<?xml version="1.0" encoding="utf-8"?> Grilled Salmon Seafood Pasta Linguini al Pesto Rack of Lamb Ribs and Wings
NOTE
Be aware that the preceding sample was run with the Saxon processor. If you use another processor, the result might be slightly different. MSXSL generates UTF-16 output by default, so the result when using MSXSL will have spaces between each letter.
Listing 3.3 shows the value of all the child nodes of the entrees node. If you remember yesterday's lesson, that is exactly right, as line 6 of Listing 3.2 asks for the value of the entrees node. That node's value contains all its descendant nodes. Getting its value yields the text value of the descendant elements. This scenario is a bit confusing because it looks like Listing 3.2 actually selects a node-set consisting of all the child elements of the entrees node. If the entrees node also contains a text value, you would see that this isn't true. You can, however, create an additional template to handle the dish elements, as shown in Listing 3.4.
注:Listing 3.3显示的是entrees节点的所有子节点的值。这个节点包含所有的子孙节点,获取值就是子孙节点的值。这种情况有点令人迷惑:它实际获取的是包含所有子孙节点的一个节点集。如果entrees节点本身也含有值的话,情况会变化的。让然,你可以继续用template深入到它的子节点去处理dish元素。
(我的体会:子(或孙)节点的值归属于父(或祖)节点,即,如果你不对子孙节点进一步定义的话,匹配父(或祖)节点时获得的值就是子(或孙)节点的值。这是xslt默认的规则。如果你详细定义了子节点,那么这一默认值对于相应的父(或祖)节点无效。)
Listing 3.4 Stylesheet with More Control over dish Elements
1: <?xml version="1.0" encoding="UTF-8"?>
2: <xsl:stylesheet version="1.0"
3: xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
4:
5: <xsl:template match="/">
6: <xsl:apply-templates />
7: </xsl:template>
8:
9: <xsl:template match="/menu/appetizers" />
10:
11: <xsl:template match="/menu/entrees">
12: Entrees:
13: <xsl:apply-templates />
14: </xsl:template>
15:
16: <xsl:template match="/menu/desserts" />
17:
18: <xsl:template match="dish">
19: <xsl:value-of select="text()" />
20: </xsl:template>
21:
22: </xsl:stylesheet>
In Listing 3.4, note that lines 9 and 16 effectively ignore the appetizers and desserts nodes in Listing 3.1 to keep the result small and to the point. The result of applying Listing 3.4 to Listing 3.1 is shown in Listing 3.5.
注:第9和16行实际上对于appetizers节点desserts的子节点的值不处理,因为text()值只对第11到14行中定义明确的entrees节点有效。
Listing 3.5 Result from Applying Listing 3.4 to Listing 3.1
<?xml version="1.0" encoding="utf-8"?>
Entrees:
Grilled Salmon
Seafood Pasta
Linguini al Pesto
Rack of Lamb
Ribs and Wings
In Listing 3.5, each dish node is now handled separately. The hyphen (-) in front of each dish shows that this is really the case. The whitespace appears, as I said before, because of the processor's default whitespace rules. |
|
|