Mouse and people's best arrangement plan
This article is inspired by a weekend that is unlocked. My decision and colleagues go to Las Vegas for a celebration, just I plan to go to IKEA home to pick a bookcase, so that I can finally tie my book after moving to the Legend Mon for a few months. After the IKEA homes for two hours, I found a bookcase that showed a bookcase with my room, just some of the necessary accessories. In the end, I order this bookcase, and I will go home when I go home. However, I have explained the books, which are scattered in the various corners of the room. This has become the best opportunity to organize my growing book library, of course, I choose to use XML to implement this task. (This article contains some links to English sites.)
Not only is the surface is so simple
The main purpose of the XML classification is to build a structure to centrally store information about the books I have, it should be flexible and can be inquiry and various demos, and it is also easy to carry. Below is an excerpt of the first draft of this document:
Books.xml
XML Version = "1.0" encoding = "UTF-8"?>
I hope to use the on-loan property to track if I borrow a book. The on-loan attribute on the root element specifies that at least one book is borrowed out, then specifies the same attribute on each BOOK element. It seems that this may not be the best design because it causes unnecessary links between root elements and child elements, but please understand, this is just my first draft.
After the simple format is designed, I decided to run some actual queries to see if this format meets my needs. I tried
The first query using Selectsinglenode Method in the System.xml.xmlnode class is as follows:
// * [position () = 1] / @ on-loan
I originally means "select all nodes in the document, then give me the on-loan property of the first node." Query returns the following:
On-loan = "yes"
Therefore, the answer to the question "I have a book borrowed?" Is YES. However, when I simulates if a book is borrowed, I have an interesting thing when I don't have anything on the on-loan value on the root element. I remove the ON-LOAN property from the root element and run the query again. The results are as follows:
On-loan = "sanjay"
The result is the value of a child element of the root element. I suspect an error, so I try to query on MSXML or get similar results. Further studies have made me a very inspirated discussion with some XPath experts in the group, and further read XPath recommendations. I found that there are some weird, personality and inconsistent situations, (ie, traps that need to be avoided when processing XPath). Abbreviations and their true meaning
XPath recommends some axes that contain some nodes associated with the current selection node (also known as context node). In order to avoid lengthy, some abbreviations are specified. The following table shows these abbreviations and their equivalent axes.
Self :: node () .. parent :: node () /// descendent-or-self :: node () / @ attribute ::
Another fact is that the default shaft used in each position step or path expression is a Child :: axis. So, / BK: BOOKS / BK: BOOK actual equivalent / child :: bk: Book / Child :: BK: BOOK, this is much easier to type directly.
Node tests are used to select all nodes of the primary node type of the current axis. * Is a node test, not an abbreviation. Finally, the number of predicates with numbers is equivalent to checking whether the position of the context node is the same as the number. This means query / bk: book [1] is equivalent to / bk: book [position () = 1].
With the above information, we can return to the original question to see why they get unexpected results. // * [position () = 1] / @ on-loan is actually / descendent-or-self :: node () / child :: * [position () = 1] / @ on-loan abbreviation, it selection Each node in the document retrieves the ON-LOAN property of "the first child node of each selected node". Want to use parentheses quickly solve this problem, (// *) [position () = 1] / @ on-loan (it is (/ descendent-or-self :: node () / child :: *) [ Position () = 1] / @ on-loan abbreviation) is what I do actually want.
Interestingly, shortly after the problem solving, I realized that the simpler and more effective query that I demanded can be:
/ * / @ on-loan
This is a better solution because it only needs to view the first node in the document. I will retain multiple examples, which emphasizes why one person should consider the content represented by the abbreviations to avoid confusing results.
abbreviation
Complete query
search result
// * [1] / descendent-or-self :: node () / child :: * [position () = 1] Select the first child node of each node in the document. (// *) [1] (/ descendent-or-self :: node () / child :: *) [Position () = 1] Select the first node in the document.
?
?
Improve our mathematical skills
Query involving relationships or arithmetic operators and strings typically leads to results that do not match intuition. XPath converts all operands in the expression of a relationship or an arithmetic operator to a number. The string of incomplete is the digital value will be converted to nan (not a number). The following table shows some XPath expressions, expressions implicitly converted to the results of the expression.
Expression implicit conversion results' 5 ' 75 712'5' '7'5 7125 ' a'5 nannan'5 '<75 <7true'5' <'7'5 <7true'5' <'B'5
Another interesting arithmetic definition is to define a pulse number (eg -6 is a valid XPath expression), but not defined a dollar plus ( 6 is not a valid XPath expression). More surprising is that multiple negation can be stacked together, but still valid. Therefore, ---- 6 is an effective XPath expression, equivalent to value 6.
XPath lacks support for scientific / exponential counting will make users make mistakes because they support its existing query languages (such as SQL), there are popular programming languages (such as C ).
The expression of combining arithmetic and relationship calculations on node collection may also result in an astonishing result. The arithmetic operation on the node collection converts the value of the "first node" in the collection into numbers, and the relational operator will determine whether any node in the "node collection" is satisfied. Below is an XML document that shows how the arithmetic operation and relationship operator causing an expression that does not associative (bind).
Numbers.xml
The following table shows the lack of arithmetic operations.
Expression results Interpretation Root / NumBers [Integer / @ value> 4 - 1]
When isn't a collection?
While the node collection is unordered, it is like a collection in mathematics (or your favorite programming language), but it is often different from the collection of mathematics in the sense of processing. Some operations in XPath use "first" semantics when processing nodes, while other operations use "any" semantics. The "first" semantic means that the value of the node collection of the operation is obtained from the first node in the collection, and the "arbitrary" semantic means that the operation in the node collection depends on whether any of the nodes in the collection will meet the condition. The section titled "Improve Math Skills" will introduce the use of "arbitrary" and "first" semantic situations.
Another feature of the XPath node collection and mathematical collection is that XPath does not directly provide a mechanism to perform a collection operation (such as subset, intersection or symmetric difference). Michael Kay
What is the earliest discovery of XSLT Programmer's Reference 2nd Edition
Count () function and the joint operator | to simulate the lack of collection operators. The XSLT style sheet for performing a collection operation of the XML document in the above section is listed below and its output.
Style sheet
XSL: for-each select = "$ a [count (. | $ b)! = count ($ b)] | $ b [count (. | $ a)! = count ($ a)]>
Set A: {4, 2, 3,} set B: {4, 3,} set c: {3,} a Union B: {4, 2, 3,} B Union C: {4, 3,} A INTERSECTION B: {4, 3,} a Difference B: {2,} a Difference C: {4, 2,} a subset of b: {false} b subset of A: {TRUE }?
The last point of the difference between node collection and mathematical collections is that the node collection is usually in order. W3C XPath recommends depicting them as disorder, but XSLT does specify the order in which node collection is specified. The identification crisis is in XPath, and does not directly determine the configuration of the equivalent node in the node identifier or the collection of different nodes. It is not directly supported, for example, whether the node returned by / BK: Books is the same as the node returned by / BK: BOOKS / BK: BOK [1] / PARENT:: *. Using the = comparison of the operator on the node collection does not compare the node collection as a whole, but use "any" semantics. Suggestions from W3C XPath:
"If the two objects to be compared are a set of nodes, when there is a node in the first node collection and a node in the second node set, this comparison is TRUE, which is in two nodes. The result of comparing on string values is True. "
To explain this, the following is a table that shows the results of the relevant node collection comparison operation result from the XML classification format. Please note that these first look like the contradictions.
Expression results Explanation // BK: BOOK = / BK: BOOKS / BK: BOOK [1] True is // BK: Book at least one node and / BK: BOOKS / BK: BOOK [1]] another node Have the same string value? // BK: book! = / bk: Books / Bk: BOOK [1] True is // BK: Book at least one node and / BK: BOOKS / BK: BOOK [1] is different from the other node String value? NOT (// BK: BOOK = / BK: BOOKS / BK: BOOK [1]) False Problem "Whether // BK: Book at least one node and / BK: BOOKS / BK: BOOK [1] in another The opposite answer of the node has the same string value. " You can use the xpath count () function to imitate the node identifier, determine if the intersection of the two nodes set of the same length is the same length of any node set, or whether it is equal to 1 in the case of a single element node set. For example, the following query returns True in this case because both nodes are the same. Count (/ BK: Books | / BK: BOOKS / BK: BOOK [1] / PARENT :: *) = 1 You can also use the generate-id () function in the XSLT to imitate the node identity. XSLT FAQ provides examples using generate-id (). I am, I am in a clear mechanism that there is no test node, but it does happen in some expressions involving the node collection. The node collection of the non-existing node is expressed as an empty node collection. In the case of a string and numerical operation, an empty node set is implicitly converted to an empty string or a nan. If you do not view an instance document when you perform a query, it is not determined that the empty node set results in which instances (and no occurrence), the series implicit conversion may result in a confusing result. Below is some examples of queries, involving empty node sets and how these implicit conversions affect them. Results Expression / NonExistentNode 5NaN / NonExistentNode = 5False / NonExistentNode! = 5Falseconcat (/ NonExistentNode, "hello") "hello" / Root [@nonExistentAttribute] does not return results / Root [@nonExistentAttribute <5] does not return results / Root [ @noneXistentAttribute> 5] Do not return the result Since the node may contain an empty string, it is generally best to use the boolean () function instead of checking the presence of the node by checking the string value of the node. For example, the following query (returning false) is a great way to affirm it in your documentation without nonnexistentNode. Boolean (/ NonexistentNode) Namespace and XPath Redux Process the defects when the namespace in XPath, involves mapping the prefix and namespace names in the expression even if the document uses the default namespace. Interesting is for a document, there is always at least one namespace node to use: XML namespace http://www.w3.org/1998/namespace. For example, look at the following query: / bk: Books / namespace :: * This query will return the following:
URN: XMLns: 25HOURSADAY-COM: my-bookshelfhttp://www.w3.org/xml/1998/namespace?