# MixedContent.jws Sample

This topic inludes the source code for the MixedContent.jws Sample.

## Sample Location

This sample is located in the following directory in your WebLogic Workshop installation:

BEA_HOME/weblogic81/samples/workshop/SamplesApp/WebServices/xmlBeans/cursor/

## Sample Source Code

`001 package xmlBeans.cursor; 002 003 import com.bea.xml.XmlCursor; 004 import org.openuri.bea.samples.workshop.xmlBeans.mixedContent.DescriptionType; 005 import org.openuri.bea.samples.workshop.xmlBeans.mixedContent.InventoryDocument; 006 import org.openuri.bea.samples.workshop.xmlBeans.mixedContent.InventoryDocument.Inventory; 007 import org.openuri.bea.samples.workshop.xmlBeans.mixedContent.ItemType; 008 009 /** 010 * A web service illustrating how you can use an XML cursor 011 * to manipulate the content of an element. While working with 012 * strongly-typed XML (in which you are accessing the XML 013 * through an API generated from schema) provides easy 014 * access for getting and setting the entire value of an 015 * element or attribute, it does not easily provide finer 016 * grained access to an element's content. This web service 017 * shows how you can use an XML cursor to "dive into" an 018 * element's content, manipulating it on a character-by- 019 * character level. <br/><br/> 020 * 021 * The code in this web service is designed to look at the 022 * description of each item in an inventory list, creating 023 * a link wherever the description contains a reference 024 * to another item in the inventory list. This alters the 025 * description element so that it contains a mix of text and 026 * link elements. Such an element is said to have "mixed 027 * content." 028 * 029 * @common:target-namespace namespace="http://workshop.bea.com/MixedContent" 030 */ 031 public class MixedContent implements com.bea.jws.WebService 032 { 033 /** 034 * Creates links between items in an inventory list by inserting 035 * a &lt;link&gt; element for each linked item. An XmlCursor 036 * instance passes through each &lt;description&gt; element, looking 037 * for text matching the name of an item. <br/><br/> 038 * 039 * To test this method, paste the contents of the 040 * InventoryItem.xml file over the &lt;inventory&gt; 041 * element (and its children) provided in by Test View. 042 * Click linkItems to view the XML produced by this code. 043 * 044 * @common:operation 045 */ 046 public InventoryDocument linkItems(InventoryDocument inventoryDoc) 047 { 048 /** 049 * Retrieve the inventory element and get an array of 050 * the item elements it contains. 051 */ 052 Inventory inventory = inventoryDoc.getInventory(); 053 ItemType[] items = inventory.getItemArray(); 054 055 /** 056 * Loop through the item elements, examining the 057 * description for each to see if another inventory item 058 * is mentioned. 059 */ 060 for (int i = 0; i < items.length; i++) 061 { 062 /** 063 * Get details about the current item, including 064 * its length. This will be used to measure text 065 * while exploring the description. 066 */ 067 String itemName = items[i].getName(); 068 String itemId = new Integer(items[i].getId()).toString(); 069 int itemCharCount = itemName.length(); 070 071 /** 072 * Loop through the item descriptions, looking at each 073 * for the name of the current item. 074 */ 075 for (int j = 0; j < items.length; j++) 076 { 077 DescriptionType description = items[j].getDescription(); 078 079 /** 080 * Insert an XmlCursor instance and set it at 081 * the beginning of the description element's text, 082 * just after the start tag. 083 */ 084 XmlCursor cursor = description.newCursor(); 085 cursor.toLastAttribute(); 086 cursor.toNextToken(); 087 088 /** 089 * Get a String containing the characters to the 090 * immediate right of the cursor, up to the next 091 * token (in this case, the next element after 092 * the description element). Get the number of 093 * characters to the right of the cursor; this will 094 * be used to mark the distance the cursor should move 095 * before trying another item's description. Also, 096 * create a charCount variable to mark the cursor's 097 * current position. 098 */ 099 String cursorChars = cursor.getChars(); 100 int descCharCount = cursorChars.length(); 101 int charCount = 0; 102 103 /** 104 * As long at the cursor hasn't reached the end of the 105 * description text, check to see if the text to the 106 * cursor's immediate right matches the item name sought. 107 * If it does match, remove the text and create a link 108 * element to replace it. 109 */ 110 while (charCount < descCharCount) 111 { 112 /** 113 * A char array to hold the characters currently being 114 * checked. 115 */ 116 char[] chars = new char[itemCharCount]; 117 118 /** 119 * Pass the char array with the getChars method. This 120 * method will find the chars from the cursor's 121 * immediate right to the char at itemCharCount (the 122 * length of the item name currently sought). The 123 * method's second argument indicates where in the char 124 * array the found text should begin -- here, at the 125 * beginning. 126 */ 127 int charsReturned = cursor.getChars(chars, 0, itemCharCount); 128 129 /** 130 * If the characters in chars match the item name, then 131 * make a link from the text. 132 */ 133 if (new String(chars).equals(itemName)) 134 { 135 /** 136 * Remove the found item name. 137 */ 138 cursor.removeChars(itemCharCount); 139 /** 140 * Begin a new link element whose namespace is the 141 * same as the rest of the inventory document. The 142 * beginElement method essentially creates a new 143 * element with the name specified around the current 144 * cursor. 145 */ 146 cursor.beginElement("link", 147 "http://openuri.org/bea/samples/workshop/xmlBeans/mixedContent"); 148 /** 149 * Insert an id attribute and make its value the id of 150 * the item sought. 151 */ 152 cursor.insertAttributeWithValue("id", itemId); 153 /** 154 * Insert the item name as the element's value. 155 */ 156 cursor.insertChars(itemName); 157 } 158 /** 159 * Move on to the next character in the description. 160 */ 161 cursor.toNextChar(1); 162 /** 163 * Increment the counter tracking the cursor's position. 164 */ 165 charCount++; 166 } 167 /** 168 * Be sure to dispose of a cursor that's no longer needed. 169 * This allows it to be garbage collected. 170 */ 171 cursor.dispose(); 172 } 173 } 174 /** 175 * Return the edited document. 176 */ 177 return inventoryDoc; 178 } 179 }`