[Pre] when converting XML data, we often encounter repeated elements in XML data files. In this technology In the tutorial email, we will discuss a solution to this problem. Problem: let's take a look at the specific problem description. Assume that the following XML data file contains the following content: [/PRE] 12345 Standard Widget 54321 Turbo widget 12345 standard Widget [Pre] in the preceding XML data file, each item element is displayed separately. Please note that item number1 and item Number3 The data in is the same. However, the requirement target requires that each SKU element in the output XML data file must be unique, Add a new <quantity> element to display the data quantity of each item. The output file of the requirement target is as follows: [/PRE] <Order> <Item> <Quantity> 2 </quantity> <SKUs> 12345 </SKU> <Description> Standard Widget </description> </Item> <Item> <Quantity> 1 </quantity> <SKUs> 54321 </SKU> <Description> Turbo widget </description> </Item> </Order> Solution:[Pre] There are actually two problems to solve. First, duplicate SKU #12345 elements (entry) need to be removed ); Second, you need to provide a new <quantity> element to display the number of data items for each item. To solve these problems We need to use some advanced XSLT features. To solve the first problem, we will use the following operation of XSLT. Following and preceding operations Indicate the future and previous nodes in a for-each loop respectively ). Nodes after following Operation Judgment If it is the same as the current node, duplicate nodes are removed. To solve the second problem, we need to get the number of each item element. Fortunately, XSLT provides count) Function. Using the counting function, we can count every item element in the XML data file and The value is assigned to the new <quantity> element. [/PRE] Remove duplicate element individuals: [Pre] removing duplicate element individuals requires some tips. First, place the selected node in a for-each loop, However, the select attribute value in this loop requires some tips. In general, you will put all the items in for-each Loop, as follows: [/PRE] <XSL:For-Each select = "// order/item"> ... </XSL:For-Each> [Pre] However, each SKU element data must be unique. To achieve this conversion, we have Add additional information to the property value. This additional information will tell the conversion processor to be different from the current node only. The value of the current node. For example, if the first node is a and the next node is A, the first node is ignored. Point. If the first node is a, the next node is a, and the next node is B Value. The first node is ignored. The following is the XML expression for this method: [/PRE] <XSL:For-Each select = "// SKU [not (. = following: SKU)]"> ... </XSL:For-Each> [Pre] in the preceding XML expression, the select attribute value determines how node data is cyclically selected. It makes The value of the current node is different from that of the current node (represented. [/PRE] Count: [Pre] You need to count each SKU element and assign it to the new <quantity> element. You also need some tips. Coincidentally. We can use the count function of XSLT, but the difficulty is that the conversion processor needs to count those elements. A simple example of counting all SKU elements is as follows: [/PRE] <XSL: value-of select = "count (// SKU)"/> [Pre] in the XML expression above, it simply counts all elements that conform to the // SKU mode. However, we need It is necessary to count SKU elements that meet special conditions. The trick is that the SKU element values that meet special conditions are in each for-each Can be obtained in a loop, and is identified by a period. The key to solving the counting problem is count. Yes, you also need to use the dot (.) ID. Therefore, we can use a new variable in each for-each loop, [/PRE] <XSL: variable name = "thesku" select = "."/> [Pre] then, we can use the count function to count each SKU element, as shown below: [/PRE] <Quantity> <XSL: value-of select = "count (// SKU [. = $ thesku])"/> </quantity> Complete solution:[Pre] Now, we can combine all the content described above to get a complete solution to this problem. The following Complete Code The select attribute is used to select the unique SKU. The <quantity> element uses the Count XSLT (count) Finally, the value of the <description> element comes from the value of the original XML data file. [/PRE] <? XML version = "1.0" encoding = "UTF-8"?> <XSL: stylesheet version = "1.0" xmlns: XSL = "http://www.w3.org/1999/XSL/Transform"> <XSL: template match = "/"> <Order> <XSL: For -Each select = "// SKU [not (. = following: SKU)]"> <XSL: variable name = "thesku" select = "."/> <Item> <Quantity> <XSL: value-of select = "count (// SKU [. = $ thesku])"/> </quantity> <SKU> <XSL: value-of select = "."/> </SKU> <Description> <XSL: value-of select = "../description"/> </description> </Item> </XSL: For -Each> </Order> </XSL: Template> </XSL: stylesheet> [Pre] Editor's note: Due to technical errors, in the previous XML technical email "tokenizing strings with xalan-Java" (March 20,200 2), the code in contains an error, which is hereby corrected. The complete and correct code is as follows: [/PRE] To use the tokenize function, we'll create a template that callit, like the following: <? XML version = "1.0" encoding = "UTF-8"?> <XSL: stylesheetversion = "1.0" Xmlns: XSL = "http://www.w3.org/1999/XSL/Transform" Xmlns: xalan = "http://xml.apache.org/xalan"> <XSL: template match = "/"> <XSL: For -Each select = "// customeraddress"> <Address> <XSL: value-of select = "address1"/> </address> <City> <XSL: value-of select = "xalan: tokenize (address2, ',') [1]"/> </city> <State> <XSL: value-of select = "xalan: tokenize (address2, ',') [2]"/> </State> <Zip> <XSL: value-of select = "xalan: tokenize (address2, ',') [3]"/> </zip> </XSL: For -Each> </XSL: Template> </XSL: stylesheet> |