Changeset 1731 for trunk/docx4j/src/main
- Timestamp:
- 12/13/11 14:02:25 (5 months ago)
- Location:
- trunk/docx4j/src/main/java/org/docx4j/model/fields
- Files:
-
- 3 edited
-
FieldRef.java (modified) (3 diffs)
-
FieldsPreprocessor.java (modified) (10 diffs)
-
FieldsSimpleToComplex.xslt (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/docx4j/src/main/java/org/docx4j/model/fields/FieldRef.java
r1727 r1731 1 1 package org.docx4j.model.fields; 2 2 3 import javax.xml.bind.JAXBElement; 4 5 import org.docx4j.XmlUtils; 6 import org.docx4j.jaxb.Context; 7 import org.docx4j.wml.P; 3 8 import org.docx4j.wml.R; 9 import org.docx4j.wml.Text; 4 10 5 11 /** … … 239 245 * In general, you can "canonicalise" the field representation 240 246 * to be 241 * (i) instructions, contained within a single run (dropping rPr)247 * (i) instructions, contained within a single run 242 248 * (ii) results, immediately following, though not nec just as following siblings 243 249 * (iii) the final <w:fldChar w:fldCharType="end"/> … … 253 259 public class FieldRef { 254 260 255 private R fieldParent; 261 private P parent; 262 public P getParent() { 263 return parent; 264 } 265 public void setParent(P parent) { 266 this.parent = parent; 267 } 268 256 269 270 /** 271 * The run 272 * 273 * <w:r> 274 <w:fldChar w:fldCharType="begin"/> 275 <w:instrText xml:space="preserve"> ... </w:instrText> 276 <w:fldChar w:fldCharType="separate"/> 277 </w:r> 278 279 Store a reference to it so we can delete it. 280 */ 281 private R beginRun; 282 public R getBeginRun() { 283 return beginRun; 284 } 285 public void setBeginRun(R beginRun) { 286 this.beginRun = beginRun; 287 } 288 289 /** 290 * The run 291 * 292 <w:r> 293 <w:fldChar w:fldCharType="end"/> 294 </w:r> 295 296 Store a reference to it so we can delete it. 297 */ 298 private R endRun; 299 public R getEndRun() { 300 return endRun; 301 } 302 public void setEndRun(R endRun) { 303 this.endRun = endRun; 304 } 257 305 306 private JAXBElement<Text> instrText; 307 public JAXBElement<Text> getInstrText() { 308 return instrText; 309 } 310 public void setInstrText(JAXBElement<Text> instrText) { 311 this.instrText = instrText; 312 } 313 314 private R resultsSlot; 315 public R getResultsSlot() { 316 return resultsSlot; 317 } 318 public void setResultsSlot(R resultsSlot) { 319 this.resultsSlot = resultsSlot; 320 } 321 322 public void setResult(String val) { 323 324 Text t = null; 325 if (resultsSlot.getContent().size()==0) { 326 t = Context.getWmlObjectFactory().createText(); 327 resultsSlot.getContent().add(t); 328 } else { 329 // Assume child Text 330 t = (Text)XmlUtils.unwrap(resultsSlot.getContent().get(0)); 331 } 332 t.setValue(val); 333 } 258 334 259 335 } -
trunk/docx4j/src/main/java/org/docx4j/model/fields/FieldsPreprocessor.java
r1727 r1731 2 2 3 3 import java.io.IOException; 4 import java.util.ArrayList; 4 5 import java.util.HashMap; 6 import java.util.List; 5 7 import java.util.Map; 6 8 7 9 import javax.xml.bind.JAXBContext; 10 import javax.xml.bind.JAXBElement; 8 11 import javax.xml.bind.Unmarshaller; 12 import javax.xml.namespace.QName; 9 13 import javax.xml.transform.Source; 10 14 import javax.xml.transform.Templates; … … 26 30 import org.docx4j.wml.P; 27 31 import org.docx4j.wml.R; 32 import org.docx4j.wml.RPr; 28 33 import org.docx4j.wml.STFldCharType; 34 import org.docx4j.wml.Text; 29 35 30 36 /** … … 42 48 43 49 private static Logger log = Logger.getLogger(FieldsPreprocessor.class); 50 51 private final static QName _RInstrText_QNAME = new QName("http://schemas.openxmlformats.org/wordprocessingml/2006/main", 52 "instrText"); 44 53 45 54 static Templates xslt; … … 100 109 // } 101 110 102 public static P canonicalise(P p ) {111 public static P canonicalise(P p, List<FieldRef> fieldRefs) { 103 112 /* 104 113 * Result is something like: … … 126 135 R newR = Context.getWmlObjectFactory().createR(); 127 136 137 RPr fieldRPr = null; 138 139 FieldRef currentField = null; 140 128 141 for (Object o : p.getContent() ) { 129 142 130 143 if ( o instanceof R ) { 131 132 for (Object o2 : ((R)o).getContent() ) { 144 145 R existingRun = (R)o; 146 for (Object o2 : existingRun.getContent() ) { 133 147 134 148 if (isCharType(o2, STFldCharType.BEGIN)) { … … 140 154 if (newR.getContent().size()>0) { 141 155 newP.getContent().add(newR); 156 157 newR.setRPr(existingRun.getRPr() ); // if any 142 158 } 143 159 144 160 newR = Context.getWmlObjectFactory().createR(); 145 161 newR.getContent().add(o2); 162 163 // Setup our FieldRef object - only top level fields for now 164 currentField = new FieldRef(); 165 fieldRefs.add(currentField); 166 currentField.setParent(newP); 167 currentField.setBeginRun(newR); 168 146 169 } 147 170 } … … 152 175 // Top level field end - gets its own w:r 153 176 newP.getContent().add(newR); 177 154 178 newR = Context.getWmlObjectFactory().createR(); 155 179 newR.getContent().add(o2); 180 newP.getContent().add(newR); 181 182 currentField.setEndRun(newR); 183 156 184 newR = Context.getWmlObjectFactory().createR(); 157 185 } else { … … 165 193 newP.getContent().add(newR); 166 194 newR = Context.getWmlObjectFactory().createR(); 195 196 // May as well set this; we'll insert our result into 197 // this (or recreate it). 198 newR.setRPr(fieldRPr ); 199 200 currentField.setResultsSlot(newR); // FIXME: ensure newR is actually added! 201 167 202 } 203 } else if (o2 instanceof JAXBElement 204 && ((JAXBElement)o2).getName().equals(_RInstrText_QNAME)) { 205 206 currentField.setInstrText( (JAXBElement<Text>)o2); 207 208 newR.getContent().add(o2); 209 210 fieldRPr = existingRun.getRPr(); 211 newR.setRPr(fieldRPr); 168 212 169 213 } else { … … 227 271 WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load( 228 272 new java.io.File( 229 System.getProperty("user.dir") + "/ simpledatefield.docx"));273 System.getProperty("user.dir") + "/mergefield1.docx")); 230 274 231 275 complexifyFields(wordMLPackage.getMainDocumentPart() ); … … 237 281 new TraversalUtil(wordMLPackage.getMainDocumentPart().getContent(), fl); 238 282 log.info("Found " + fl.starts.size() + " fields "); 283 284 List<FieldRef> fieldRefs = new ArrayList<FieldRef>(); 285 239 286 for( P p : fl.starts) { 240 287 int index = ((ContentAccessor)p.getParent()).getContent().indexOf(p); 241 P newP = canonicalise(p );288 P newP = canonicalise(p, fieldRefs); 242 289 System.out.println("NewP length: " + newP.getContent().size() ); 243 290 ((ContentAccessor)p.getParent()).getContent().set(index, newP); 244 291 } 245 292 293 // Prove we can put something into the results 294 int counter = 0; 295 for (FieldRef fr : fieldRefs) { 296 fr.setResult("Result" + counter); 297 counter++; 298 299 // If doing an actual mail merge, the begin-separate run is removed, as is the end run 300 fr.getParent().getContent().remove(fr.getBeginRun()); 301 fr.getParent().getContent().remove(fr.getEndRun()); 302 } 303 246 304 System.out.println(XmlUtils.marshaltoString(wordMLPackage.getMainDocumentPart().getJaxbElement(), true, true)); 247 305 248 306 wordMLPackage.save(new java.io.File( 249 System.getProperty("user.dir") + "/ simpledatefield-COMPLEX.docx") );307 System.getProperty("user.dir") + "/mergefield1-OUT.docx") ); 250 308 251 309 -
trunk/docx4j/src/main/java/org/docx4j/model/fields/FieldsSimpleToComplex.xslt
r1727 r1731 56 56 <xsl:template match="w:fldSimple" > 57 57 <w:r> 58 <!-- Keep any rPr, so we can preserve bold, italic, underline etc --> 59 <xsl:copy-of select="w:r/w:rPr" /> 60 58 61 <w:fldChar w:fldCharType="begin"/> 59 62 <w:instrText xml:space="preserve"><xsl:value-of select="@w:instr"></xsl:value-of> </w:instrText>
Note: See TracChangeset
for help on using the changeset viewer.
