Patch from Fabian from bug #52285 - support Smart Tags in XWPF paragraphs, with test (and fixing indents)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1210774 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
9068469566
commit
693a7ddc09
@ -34,6 +34,7 @@
|
|||||||
|
|
||||||
<changes>
|
<changes>
|
||||||
<release version="3.8-beta5" date="2011-??-??">
|
<release version="3.8-beta5" date="2011-??-??">
|
||||||
|
<action dev="poi-developers" type="add">52285 - Support XWPF smart tags text in Paragraphs</action>
|
||||||
<action dev="poi-developers" type="fix">51875 - More XSSF new-line in formula support</action>
|
<action dev="poi-developers" type="fix">51875 - More XSSF new-line in formula support</action>
|
||||||
<action dev="poi-developers" type="add">POIFS EntryUtils.copyNodes(POFS,POIFS) now uses FilteringDirectoryNode, so can exclude from copying nodes not just directly under the root</action>
|
<action dev="poi-developers" type="add">POIFS EntryUtils.copyNodes(POFS,POIFS) now uses FilteringDirectoryNode, so can exclude from copying nodes not just directly under the root</action>
|
||||||
<action dev="poi-developers" type="add">POIFS Helper FilteringDirectoryNode, which wraps a DirectoryEntry and allows certain parts to be ignored</action>
|
<action dev="poi-developers" type="add">POIFS Helper FilteringDirectoryNode, which wraps a DirectoryEntry and allows certain parts to be ignored</action>
|
||||||
|
@ -41,6 +41,7 @@ import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRunTrackChange;
|
|||||||
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtContentRun;
|
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtContentRun;
|
||||||
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtRun;
|
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtRun;
|
||||||
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSimpleField;
|
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSimpleField;
|
||||||
|
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSmartTagRun;
|
||||||
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSpacing;
|
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSpacing;
|
||||||
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTString;
|
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTString;
|
||||||
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTText;
|
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTText;
|
||||||
@ -73,52 +74,17 @@ public class XWPFParagraph implements IBodyElement {
|
|||||||
throw new NullPointerException();
|
throw new NullPointerException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Build up the character runs
|
||||||
runs = new ArrayList<XWPFRun>();
|
runs = new ArrayList<XWPFRun>();
|
||||||
|
buildRunsInOrderFromXml(paragraph);
|
||||||
// Get all our child nodes in order, and process them
|
|
||||||
// into XWPFRuns where we can
|
|
||||||
XmlCursor c = paragraph.newCursor();
|
|
||||||
c.selectPath("child::*");
|
|
||||||
while (c.toNextSelection()) {
|
|
||||||
XmlObject o = c.getObject();
|
|
||||||
if(o instanceof CTR) {
|
|
||||||
runs.add(new XWPFRun((CTR)o, this));
|
|
||||||
}
|
|
||||||
if(o instanceof CTHyperlink) {
|
|
||||||
CTHyperlink link = (CTHyperlink)o;
|
|
||||||
for(CTR r : link.getRList()) {
|
|
||||||
runs.add(new XWPFHyperlinkRun(link, r, this));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(o instanceof CTSdtRun) {
|
|
||||||
CTSdtContentRun run = ((CTSdtRun)o).getSdtContent();
|
|
||||||
for(CTR r : run.getRList()) {
|
|
||||||
runs.add(new XWPFRun(r, this));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(o instanceof CTRunTrackChange) {
|
|
||||||
for(CTR r : ((CTRunTrackChange)o).getRList()) {
|
|
||||||
runs.add(new XWPFRun(r, this));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(o instanceof CTSimpleField) {
|
|
||||||
for(CTR r : ((CTSimpleField)o).getRList()) {
|
|
||||||
runs.add(new XWPFRun(r, this));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
c.dispose();
|
|
||||||
|
|
||||||
// Look for bits associated with the runs
|
// Look for bits associated with the runs
|
||||||
for(XWPFRun run : runs) {
|
for(XWPFRun run : runs) {
|
||||||
CTR r = run.getCTR();
|
CTR r = run.getCTR();
|
||||||
|
|
||||||
// Check for bits that only apply when
|
// Check for bits that only apply when attached to a core document
|
||||||
// attached to a core document
|
|
||||||
// TODO Make this nicer by tracking the XWPFFootnotes directly
|
// TODO Make this nicer by tracking the XWPFFootnotes directly
|
||||||
if(document != null) {
|
XmlCursor c = r.newCursor();
|
||||||
c = r.newCursor();
|
|
||||||
c.selectPath("child::*");
|
c.selectPath("child::*");
|
||||||
while (c.toNextSelection()) {
|
while (c.toNextSelection()) {
|
||||||
XmlObject o = c.getObject();
|
XmlObject o = c.getObject();
|
||||||
@ -145,6 +111,49 @@ public class XWPFParagraph implements IBodyElement {
|
|||||||
c.dispose();
|
c.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Identifies (in order) the parts of the paragraph /
|
||||||
|
* sub-paragraph that correspond to character text
|
||||||
|
* runs, and builds the appropriate runs for these.
|
||||||
|
*/
|
||||||
|
private void buildRunsInOrderFromXml(XmlObject object) {
|
||||||
|
XmlCursor c = object.newCursor();
|
||||||
|
c.selectPath("child::*");
|
||||||
|
while (c.toNextSelection()) {
|
||||||
|
XmlObject o = c.getObject();
|
||||||
|
if (o instanceof CTR) {
|
||||||
|
runs.add(new XWPFRun((CTR) o, this));
|
||||||
|
}
|
||||||
|
if (o instanceof CTHyperlink) {
|
||||||
|
CTHyperlink link = (CTHyperlink) o;
|
||||||
|
for (CTR r : link.getRList()) {
|
||||||
|
runs.add(new XWPFHyperlinkRun(link, r, this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (o instanceof CTSdtRun) {
|
||||||
|
CTSdtContentRun run = ((CTSdtRun) o).getSdtContent();
|
||||||
|
for (CTR r : run.getRList()) {
|
||||||
|
runs.add(new XWPFRun(r, this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (o instanceof CTRunTrackChange) {
|
||||||
|
for (CTR r : ((CTRunTrackChange) o).getRList()) {
|
||||||
|
runs.add(new XWPFRun(r, this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (o instanceof CTSimpleField) {
|
||||||
|
for (CTR r : ((CTSimpleField) o).getRList()) {
|
||||||
|
runs.add(new XWPFRun(r, this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (o instanceof CTSmartTagRun) {
|
||||||
|
// Smart Tags can be nested many times.
|
||||||
|
// This implementation does not preserve the tagging information
|
||||||
|
buildRunsInOrderFromXml(o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Internal
|
@Internal
|
||||||
|
@ -0,0 +1,39 @@
|
|||||||
|
/* ====================================================================
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
contributor license agreements. See the NOTICE file distributed with
|
||||||
|
this work for additional information regarding copyright ownership.
|
||||||
|
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
(the "License"); you may not use this file except in compliance with
|
||||||
|
the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
==================================================================== */
|
||||||
|
package org.apache.poi.xwpf.usermodel;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
import org.apache.poi.xwpf.XWPFTestDataSamples;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for reading SmartTags from Word docx.
|
||||||
|
*
|
||||||
|
* @author Fabian Lange
|
||||||
|
*/
|
||||||
|
public final class TestXWPFSmartTag extends TestCase {
|
||||||
|
|
||||||
|
public void testSmartTags() throws IOException {
|
||||||
|
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("smarttag-snippet.docx");
|
||||||
|
XWPFParagraph p = doc.getParagraphArray(0);
|
||||||
|
assertTrue(p.getText().contains("Carnegie Mellon University School of Computer Science"));
|
||||||
|
p = doc.getParagraphArray(2);
|
||||||
|
assertTrue(p.getText().contains("Alice's Adventures"));
|
||||||
|
}
|
||||||
|
}
|
BIN
test-data/document/smarttag-snippet.docx
Normal file
BIN
test-data/document/smarttag-snippet.docx
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user