public class FieldStart extends FieldChar
To learn more, visit the Working with Fields documentation article.
Remarks:
FieldStart is an inline-level node and represented by the ControlChar.FIELD_START_CHAR control character in the document.
FieldStart can only be a child of Paragraph.
A complete field in a Microsoft Word document is a complex structure consisting of a field start character, field code, field separator character, field result and field end character. Some fields only have field start, field code and field end.
To easily insert a new field into a document, use the DocumentBuilder.insertField(java.lang.String) method.
Examples:
Shows how to work with a collection of fields.
public void fieldCollection() throws Exception {
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);
builder.insertField(" DATE \\@ \"dddd, d MMMM yyyy\" ");
builder.insertField(" TIME ");
builder.insertField(" REVNUM ");
builder.insertField(" AUTHOR \"John Doe\" ");
builder.insertField(" SUBJECT \"My Subject\" ");
builder.insertField(" QUOTE \"Hello world!\" ");
doc.updateFields();
FieldCollection fields = doc.getRange().getFields();
Assert.assertEquals(6, fields.getCount());
// Iterate over the field collection, and print contents and type
// of every field using a custom visitor implementation.
FieldVisitor fieldVisitor = new FieldVisitor();
Iterator<Field> fieldEnumerator = fields.iterator();
while (fieldEnumerator.hasNext()) {
if (fieldEnumerator != null) {
Field currentField = fieldEnumerator.next();
currentField.getStart().accept(fieldVisitor);
if (currentField.getSeparator() != null) {
currentField.getSeparator().accept(fieldVisitor);
}
currentField.getEnd().accept(fieldVisitor);
} else {
System.out.println("There are no fields in the document.");
}
}
System.out.println(fieldVisitor.getText());
}
/// <summary>
/// Document visitor implementation that prints field info.
/// </summary>
public static class FieldVisitor extends DocumentVisitor {
public FieldVisitor() {
mBuilder = new StringBuilder();
}
/// <summary>
/// Gets the plain text of the document that was accumulated by the visitor.
/// </summary>
public String getText() {
return mBuilder.toString();
}
/// <summary>
/// Called when a FieldStart node is encountered in the document.
/// </summary>
public int visitFieldStart(final FieldStart fieldStart) {
mBuilder.append("Found field: " + fieldStart.getFieldType() + "\r\n");
mBuilder.append("\tField code: " + fieldStart.getField().getFieldCode() + "\r\n");
mBuilder.append("\tDisplayed as: " + fieldStart.getField().getResult() + "\r\n");
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when a FieldSeparator node is encountered in the document.
/// </summary>
public int visitFieldSeparator(final FieldSeparator fieldSeparator) {
mBuilder.append("\tFound separator: " + fieldSeparator.getText() + "\r\n");
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when a FieldEnd node is encountered in the document.
/// </summary>
public int visitFieldEnd(final FieldEnd fieldEnd) {
mBuilder.append("End of field: " + fieldEnd.getFieldType() + "\r\n");
return VisitorAction.CONTINUE;
}
private final StringBuilder mBuilder;
}
Shows how to find all hyperlinks in a Word document, and then change their URLs and display names.
import com.aspose.words.*;
import org.testng.annotations.Test;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ExReplaceHyperlinks extends ApiExampleBase {
public void fields() throws Exception {
Document doc = new Document(getMyDir() + "Hyperlinks.docx");
// Hyperlinks in a Word documents are fields. To begin looking for hyperlinks, we must first find all the fields.
// Use the "SelectNodes" method to find all the fields in the document via an XPath.
NodeList fieldStarts = doc.selectNodes("//FieldStart");
for (FieldStart fieldStart : (Iterable<FieldStart>) fieldStarts) {
if (fieldStart.getFieldType() == FieldType.FIELD_HYPERLINK) {
Hyperlink hyperlink = new Hyperlink(fieldStart);
// Hyperlinks that link to bookmarks do not have URLs.
if (hyperlink.isLocal()) continue;
// Give each URL hyperlink a new URL and name.
hyperlink.setTarget(NEW_URL);
hyperlink.setName(NEW_NAME);
}
}
doc.save(getArtifactsDir() + "ReplaceHyperlinks.Fields.docx");
}
private static final String NEW_URL = "http://www.aspose.com";
private static final String NEW_NAME = "Aspose - The .NET & Java Component Publisher";
}
// This "facade" class makes it easier to work with a hyperlink field in a Word document.
// <p>
// HYPERLINK fields contain and display hyperlinks in the document body. A field in Aspose.Words
// consists of several nodes, and it might be difficult to work with all those nodes directly.
// This implementation will work only if the hyperlink code and name each consist of only one Run node.
// <p>
// The node structure for fields is as follows:
// <p>
// [FieldStart][Run - field code][FieldSeparator][Run - field result][FieldEnd]
// <p>
// Below are two example field codes of HYPERLINK fields:
// HYPERLINK "url"
// HYPERLINK \l "bookmark name"
// <p>
// A field's "Result" property contains text that the field displays in the document body to the user.
class Hyperlink {
Hyperlink(final FieldStart fieldStart) throws Exception {
if (fieldStart == null) {
throw new IllegalArgumentException("fieldStart");
}
if (fieldStart.getFieldType() != FieldType.FIELD_HYPERLINK) {
throw new IllegalArgumentException("Field start type must be FieldHyperlink.");
}
mFieldStart = fieldStart;
// Find the field separator node.
mFieldSeparator = findNextSibling(mFieldStart, NodeType.FIELD_SEPARATOR);
if (mFieldSeparator == null) {
throw new IllegalStateException("Cannot find field separator.");
}
// Normally, we can always find the field's end node, but the example document
// contains a paragraph break inside a hyperlink, which puts the field end
// in the next paragraph. It will be much more complicated to handle fields which span several
// paragraphs correctly. In this case allowing field end to be null is enough.
mFieldEnd = findNextSibling(mFieldSeparator, NodeType.FIELD_END);
// Field code looks something like "HYPERLINK "http:\\www.myurl.com"", but it can consist of several runs.
String fieldCode = getTextSameParent(mFieldStart.getNextSibling(), mFieldSeparator);
Matcher matcher = G_REGEX.matcher(fieldCode.trim());
matcher.find();
// The hyperlink is local if \l is present in the field code.
mIsLocal = (matcher.group(1) != null) && (matcher.group(1).length() > 0);
mTarget = matcher.group(2);
}
// Gets or sets the display name of the hyperlink.
String getName() throws Exception {
return getTextSameParent(mFieldSeparator, mFieldEnd);
}
void setName(final String value) throws Exception {
// Hyperlink display name is stored in the field result, which is a Run
// node between field separator and field end.
Run fieldResult = (Run) mFieldSeparator.getNextSibling();
fieldResult.setText(value);
// If the field result consists of more than one run, delete these runs.
removeSameParent(fieldResult.getNextSibling(), mFieldEnd);
}
// Gets or sets the target URL or bookmark name of the hyperlink.
String getTarget() {
return mTarget;
}
void setTarget(final String value) throws Exception {
mTarget = value;
updateFieldCode();
}
// True if the hyperlinks target is a bookmark inside the document. False if the hyperlink is a URL.
boolean isLocal() {
return mIsLocal;
}
void isLocal(final boolean value) throws Exception {
mIsLocal = value;
updateFieldCode();
}
private void updateFieldCode() throws Exception {
// A field's field code is in a Run node between the field's start node and field separator.
Run fieldCode = (Run) mFieldStart.getNextSibling();
fieldCode.setText(java.text.MessageFormat.format("HYPERLINK {0}\"{1}\"", ((mIsLocal) ? "\\l " : ""), mTarget));
// If the field code consists of more than one run, delete these runs.
removeSameParent(fieldCode.getNextSibling(), mFieldSeparator);
}
// Goes through siblings starting from the start node until it finds a node of the specified type or null.
private static Node findNextSibling(final Node startNode, final int nodeType) {
for (Node node = startNode; node != null; node = node.getNextSibling()) {
if (node.getNodeType() == nodeType) return node;
}
return null;
}
// Retrieves text from start up to but not including the end node.
private static String getTextSameParent(final Node startNode, final Node endNode) {
if ((endNode != null) && (startNode.getParentNode() != endNode.getParentNode())) {
throw new IllegalArgumentException("Start and end nodes are expected to have the same parent.");
}
StringBuilder builder = new StringBuilder();
for (Node child = startNode; !child.equals(endNode); child = child.getNextSibling()) {
builder.append(child.getText());
}
return builder.toString();
}
// Removes nodes from start up to but not including the end node.
// Assumes that the start and end nodes have the same parent.
private static void removeSameParent(final Node startNode, final Node endNode) {
if ((endNode != null) && (startNode.getParentNode() != endNode.getParentNode())) {
throw new IllegalArgumentException("Start and end nodes are expected to have the same parent.");
}
Node curChild = startNode;
while ((curChild != null) && (curChild != endNode)) {
Node nextChild = curChild.getNextSibling();
curChild.remove();
curChild = nextChild;
}
}
private final Node mFieldStart;
private final Node mFieldSeparator;
private final Node mFieldEnd;
private boolean mIsLocal;
private String mTarget;
private static final Pattern G_REGEX = Pattern.compile(
"\\S+" + // One or more non spaces HYPERLINK or other word in other languages.
"\\s+" + // One or more spaces.
"(?:\"\"\\s+)?" + // Non-capturing optional "" and one or more spaces.
"(\\\\l\\s+)?" + // Optional \l flag followed by one or more spaces.
"\"" + // One apostrophe.
"([^\"]+)" + // One or more characters, excluding the apostrophe (hyperlink target).
"\"" // One closing apostrophe.
);
}
| Modifier and Type | Method and Description |
|---|---|
boolean |
accept(DocumentVisitor visitor)
Accepts a visitor.
|
byte[] |
getFieldData()
Gets custom field data which is associated with the field.
|
int |
getNodeType()
Returns
NodeType.FIELD_START. |
getField, getFieldType, isDirty, isDirty, isLocked, isLockedgetTextclearRunAttrs, fetchInheritedRunAttr, getDirectRunAttr, getDirectRunAttr, getDocument_IInline, getFont, getParentParagraph_IInline, getParentParagraph, isDeleteRevision, isFormatRevision, isInsertRevision, isMoveFromRevision, isMoveToRevision, removeMoveRevisions, removeRunAttr, setRunAttrdeepClone, getAncestor, getAncestor, getCustomNodeId, getDocument, getNextSibling, getParentNode, getPreviousSibling, getRange, isComposite, memberwiseClone, nextPreOrder, nodeTypeToString, previousPreOrder, remove, setCustomNodeId, toString, toString, toString, visitorActionToBoolpublic int getNodeType()
NodeType.FIELD_START.
Examples:
Shows how to traverse a composite node's tree of child nodes.
public void recurseChildren() throws Exception {
Document doc = new Document(getMyDir() + "Paragraphs.docx");
// Any node that can contain child nodes, such as the document itself, is composite.
Assert.assertTrue(doc.isComposite());
// Invoke the recursive function that will go through and print all the child nodes of a composite node.
traverseAllNodes(doc, 0);
}
/// <summary>
/// Recursively traverses a node tree while printing the type of each node
/// with an indent depending on depth as well as the contents of all inline nodes.
/// </summary>
public void traverseAllNodes(CompositeNode parentNode, int depth) {
for (Node childNode = parentNode.getFirstChild(); childNode != null; childNode = childNode.getNextSibling()) {
System.out.println(MessageFormat.format("{0}{1}", String.format(" ", depth), Node.nodeTypeToString(childNode.getNodeType())));
// Recurse into the node if it is a composite node. Otherwise, print its contents if it is an inline node.
if (childNode.isComposite()) {
System.out.println();
traverseAllNodes((CompositeNode) childNode, depth + 1);
} else if (childNode instanceof Inline) {
System.out.println(MessageFormat.format(" - \"{0}\"", childNode.getText().trim()));
} else {
System.out.println();
}
}
}
getNodeType in class SpecialCharNodeType.FIELD_START. The returned value is one of NodeType constants.public boolean accept(DocumentVisitor visitor) throws java.lang.Exception
Remarks:
Calls DocumentVisitor.visitFieldStart(com.aspose.words.FieldStart).
For more info see the Visitor design pattern.
Examples:
Shows how to work with a collection of fields.
public void fieldCollection() throws Exception {
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);
builder.insertField(" DATE \\@ \"dddd, d MMMM yyyy\" ");
builder.insertField(" TIME ");
builder.insertField(" REVNUM ");
builder.insertField(" AUTHOR \"John Doe\" ");
builder.insertField(" SUBJECT \"My Subject\" ");
builder.insertField(" QUOTE \"Hello world!\" ");
doc.updateFields();
FieldCollection fields = doc.getRange().getFields();
Assert.assertEquals(6, fields.getCount());
// Iterate over the field collection, and print contents and type
// of every field using a custom visitor implementation.
FieldVisitor fieldVisitor = new FieldVisitor();
Iterator<Field> fieldEnumerator = fields.iterator();
while (fieldEnumerator.hasNext()) {
if (fieldEnumerator != null) {
Field currentField = fieldEnumerator.next();
currentField.getStart().accept(fieldVisitor);
if (currentField.getSeparator() != null) {
currentField.getSeparator().accept(fieldVisitor);
}
currentField.getEnd().accept(fieldVisitor);
} else {
System.out.println("There are no fields in the document.");
}
}
System.out.println(fieldVisitor.getText());
}
/// <summary>
/// Document visitor implementation that prints field info.
/// </summary>
public static class FieldVisitor extends DocumentVisitor {
public FieldVisitor() {
mBuilder = new StringBuilder();
}
/// <summary>
/// Gets the plain text of the document that was accumulated by the visitor.
/// </summary>
public String getText() {
return mBuilder.toString();
}
/// <summary>
/// Called when a FieldStart node is encountered in the document.
/// </summary>
public int visitFieldStart(final FieldStart fieldStart) {
mBuilder.append("Found field: " + fieldStart.getFieldType() + "\r\n");
mBuilder.append("\tField code: " + fieldStart.getField().getFieldCode() + "\r\n");
mBuilder.append("\tDisplayed as: " + fieldStart.getField().getResult() + "\r\n");
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when a FieldSeparator node is encountered in the document.
/// </summary>
public int visitFieldSeparator(final FieldSeparator fieldSeparator) {
mBuilder.append("\tFound separator: " + fieldSeparator.getText() + "\r\n");
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when a FieldEnd node is encountered in the document.
/// </summary>
public int visitFieldEnd(final FieldEnd fieldEnd) {
mBuilder.append("End of field: " + fieldEnd.getFieldType() + "\r\n");
return VisitorAction.CONTINUE;
}
private final StringBuilder mBuilder;
}
accept in class SpecialCharvisitor - The visitor that will visit the node.java.lang.Exceptionpublic byte[] getFieldData()
Examples:
Shows how to get data associated with the field.
Document doc = new Document(getMyDir() + "Field sample - Field with data.docx");
Field field = doc.getRange().getFields().get(2);
System.out.println(new String(field.getStart().getFieldData(), StandardCharsets.UTF_8));