FieldStart Class |
Namespace: Aspose.Words.Fields
The FieldStart type exposes the following members.
Name | Description | |
---|---|---|
![]() ![]() | Document |
Gets the document to which this node belongs.
(Inherited from Node.) |
![]() ![]() | FieldType |
Returns the type of the field.
(Inherited from FieldChar.) |
![]() ![]() | Font |
Provides access to the font formatting of this object.
(Inherited from Inline.) |
![]() ![]() | IsComposite |
Returns true if this node can contain other nodes.
(Inherited from Node.) |
![]() ![]() | IsDeleteRevision |
Returns true if this object was deleted in Microsoft Word while change tracking was enabled.
(Inherited from Inline.) |
![]() ![]() | IsDirty |
Gets or sets whether the current result of the field is no longer correct (stale) due to other modifications
made to the document.
(Inherited from FieldChar.) |
![]() ![]() | IsFormatRevision |
Returns true if formatting of the object was changed in Microsoft Word while change tracking was enabled.
(Inherited from Inline.) |
![]() ![]() | IsInsertRevision |
Returns true if this object was inserted in Microsoft Word while change tracking was enabled.
(Inherited from Inline.) |
![]() ![]() | IsLocked |
Gets or sets whether the parent field is locked (should not recalculate its result).
(Inherited from FieldChar.) |
![]() ![]() | IsMoveFromRevision |
Returns true if this object was moved (deleted) in Microsoft Word while change tracking was enabled.
(Inherited from Inline.) |
![]() ![]() | IsMoveToRevision |
Returns true if this object was moved (inserted) in Microsoft Word while change tracking was enabled.
(Inherited from Inline.) |
![]() ![]() | NextSibling |
Gets the node immediately following this node.
(Inherited from Node.) |
![]() ![]() | NodeType |
Returns FieldStart.
(Overrides SpecialCharNodeType.) |
![]() ![]() | ParentNode |
Gets the immediate parent of this node.
(Inherited from Node.) |
![]() ![]() | ParentParagraph |
Retrieves the parent Paragraph of this node.
(Inherited from Inline.) |
![]() ![]() | PreviousSibling |
Gets the node immediately preceding this node.
(Inherited from Node.) |
![]() ![]() | Range |
Returns a Range object that represents the portion of a document that is contained in this node.
(Inherited from Node.) |
Name | Description | |
---|---|---|
![]() ![]() | Accept |
Accepts a visitor.
(Overrides SpecialCharAccept(DocumentVisitor).) |
![]() ![]() | Clone | (Inherited from Node.) |
![]() | Equals | (Inherited from Object.) |
![]() ![]() | GetAncestor(Type) |
Gets the first ancestor of the specified object type.
(Inherited from Node.) |
![]() ![]() | GetAncestor(NodeType) |
Gets the first ancestor of the specified NodeType.
(Inherited from Node.) |
![]() ![]() | GetField |
Returns a field for the field char.
(Inherited from FieldChar.) |
![]() | GetHashCode | (Inherited from Object.) |
![]() | GetText |
Gets the special character that this node represents.
(Inherited from SpecialChar.) |
![]() | GetType | (Inherited from Object.) |
![]() ![]() | NextPreOrder |
Gets next node according to the pre-order tree traversal algorithm.
(Inherited from Node.) |
![]() ![]() | PreviousPreOrder |
Gets the previous node according to the pre-order tree traversal algorithm.
(Inherited from Node.) |
![]() ![]() | Remove |
Removes itself from the parent.
(Inherited from Node.) |
![]() | ToString | (Inherited from Object.) |
![]() ![]() | ToString(SaveFormat) |
Exports the content of the node into a string in the specified format.
(Inherited from Node.) |
![]() ![]() | ToString(SaveOptions) |
Exports the content of the node into a string using the specified save options.
(Inherited from Node.) |
FieldStart is an inline-level node and represented by the FieldStartChar 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 InsertField(String) method.
public void FieldCollection() { // Create a new document and insert some fields 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(); // Get the collection that contains all the fields in a document FieldCollection fields = doc.Range.Fields; Assert.AreEqual(6, fields.Count); // Iterate over the field collection and print contents and type of every field using a custom visitor implementation FieldVisitor fieldVisitor = new FieldVisitor(); using (IEnumerator<Field> fieldEnumerator = fields.GetEnumerator()) { while (fieldEnumerator.MoveNext()) { if (fieldEnumerator.Current != null) { fieldEnumerator.Current.Start.Accept(fieldVisitor); fieldEnumerator.Current.Separator?.Accept(fieldVisitor); fieldEnumerator.Current.End.Accept(fieldVisitor); } else { Console.WriteLine("There are no fields in the document."); } } } Console.WriteLine(fieldVisitor.GetText()); // Get a field to remove itself fields[0].Remove(); Assert.AreEqual(5, fields.Count); // Remove a field by reference Field lastField = fields[3]; fields.Remove(lastField); Assert.AreEqual(4, fields.Count); // Remove a field by index fields.RemoveAt(2); Assert.AreEqual(3, fields.Count); // Remove all fields from the document fields.Clear(); Assert.AreEqual(0, fields.Count); } /// <summary> /// Document visitor implementation that prints field info. /// </summary> public class FieldVisitor : 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 override VisitorAction VisitFieldStart(FieldStart fieldStart) { mBuilder.AppendLine("Found field: " + fieldStart.FieldType); mBuilder.AppendLine("\tField code: " + fieldStart.GetField().GetFieldCode()); mBuilder.AppendLine("\tDisplayed as: " + fieldStart.GetField().Result); return VisitorAction.Continue; } /// <summary> /// Called when a FieldSeparator node is encountered in the document. /// </summary> public override VisitorAction VisitFieldSeparator(FieldSeparator fieldSeparator) { mBuilder.AppendLine("\tFound separator: " + fieldSeparator.GetText()); return VisitorAction.Continue; } /// <summary> /// Called when a FieldEnd node is encountered in the document. /// </summary> public override VisitorAction VisitFieldEnd(FieldEnd fieldEnd) { mBuilder.AppendLine("End of field: " + fieldEnd.FieldType); return VisitorAction.Continue; } private readonly StringBuilder mBuilder; }
using System; using System.Linq; using System.Text; using System.Text.RegularExpressions; using Aspose.Words; using Aspose.Words.Fields; using NUnit.Framework; namespace ApiExamples { /// <summary> /// Shows how to replace hyperlinks in a Word document. /// </summary> public class ExReplaceHyperlinks : ApiExampleBase { /// <summary> /// Finds all hyperlinks in a Word document and changes their URL and display name. /// </summary> public void Fields() { // Specify your document name here Document doc = new Document(MyDir + "Hyperlinks.docx"); // Hyperlinks in a Word documents are fields, select all field start nodes so we can find the hyperlinks NodeList fieldStarts = doc.SelectNodes("//FieldStart"); foreach (FieldStart fieldStart in fieldStarts.OfType<FieldStart>()) { if (fieldStart.FieldType.Equals(FieldType.FieldHyperlink)) { // The field is a hyperlink field, use the "facade" class to help to deal with the field Hyperlink hyperlink = new Hyperlink(fieldStart); // Some hyperlinks can be local (links to bookmarks inside the document), ignore these if (hyperlink.IsLocal) continue; // The Hyperlink class allows to set the target URL and the display name // of the link easily by setting the properties hyperlink.Target = NewUrl; hyperlink.Name = NewName; } } doc.Save(ArtifactsDir + "ReplaceHyperlinks.Fields.docx"); } private const string NewUrl = @"http://www.aspose.com"; private const string NewName = "Aspose - The .NET & Java Component Publisher"; } /// <summary> /// This "facade" class makes it easier to work with a hyperlink field in a Word document. /// /// A hyperlink is represented by a HYPERLINK field in a Word document. A field in Aspose.Words /// consists of several nodes and it might be difficult to work with all those nodes directly. /// Note this is a simple implementation and will work only if the hyperlink code and name /// each consist of one Run only. /// /// [FieldStart][Run - field code][FieldSeparator][Run - field result][FieldEnd] /// /// The field code contains a String in one of these formats: /// HYPERLINK "url" /// HYPERLINK \l "bookmark name" /// /// The field result contains text that is displayed to the user. /// </summary> internal class Hyperlink { internal Hyperlink(FieldStart fieldStart) { if (fieldStart == null) throw new ArgumentNullException("fieldStart"); if (!fieldStart.FieldType.Equals(FieldType.FieldHyperlink)) throw new ArgumentException("Field start type must be FieldHyperlink."); mFieldStart = fieldStart; // Find the field separator node mFieldSeparator = FindNextSibling(mFieldStart, NodeType.FieldSeparator); if (mFieldSeparator == null) throw new InvalidOperationException("Cannot find field separator."); // Find the field end node. Normally field end will always be found, but in the example document // there happens to be a paragraph break included in the hyperlink and this puts the field end // in the next paragraph. It will be much more complicated to handle fields which span several // paragraphs correctly, but in this case allowing field end to be null is enough for our purposes mFieldEnd = FindNextSibling(mFieldSeparator, NodeType.FieldEnd); // Field code looks something like [ HYPERLINK "http:\\www.myurl.com" ], but it can consist of several runs string fieldCode = GetTextSameParent(mFieldStart.NextSibling, mFieldSeparator); Match match = gRegex.Match(fieldCode.Trim()); mIsLocal = match.Groups[1].Length > 0; //The link is local if \l is present in the field code mTarget = match.Groups[2].Value; } /// <summary> /// Gets or sets the display name of the hyperlink. /// </summary> internal string Name { get { return GetTextSameParent(mFieldSeparator, mFieldEnd); } set { // Hyperlink display name is stored in the field result which is a Run // node between field separator and field end Run fieldResult = (Run) mFieldSeparator.NextSibling; fieldResult.Text = value; // But sometimes the field result can consist of more than one run, delete these runs RemoveSameParent(fieldResult.NextSibling, mFieldEnd); } } /// <summary> /// Gets or sets the target url or bookmark name of the hyperlink. /// </summary> internal string Target { get { return mTarget; } set { mTarget = value; UpdateFieldCode(); } } /// <summary> /// True if the hyperlinks target is a bookmark inside the document. False if the hyperlink is a url. /// </summary> internal bool IsLocal { get { return mIsLocal; } set { mIsLocal = value; UpdateFieldCode(); } } private void UpdateFieldCode() { // Field code is stored in a Run node between field start and field separator Run fieldCode = (Run) mFieldStart.NextSibling; fieldCode.Text = string.Format("HYPERLINK {0}\"{1}\"", ((mIsLocal) ? "\\l " : ""), mTarget); // But sometimes the field code can consist of more than one run, delete these runs RemoveSameParent(fieldCode.NextSibling, mFieldSeparator); } /// <summary> /// Goes through siblings starting from the start node until it finds a node of the specified type or null. /// </summary> private static Node FindNextSibling(Node startNode, NodeType nodeType) { for (Node node = startNode; node != null; node = node.NextSibling) { if (node.NodeType.Equals(nodeType)) return node; } return null; } /// <summary> /// Retrieves text from start up to but not including the end node. /// </summary> private static string GetTextSameParent(Node startNode, Node endNode) { if ((endNode != null) && (startNode.ParentNode != endNode.ParentNode)) throw new ArgumentException("Start and end nodes are expected to have the same parent."); StringBuilder builder = new StringBuilder(); for (Node child = startNode; !child.Equals(endNode); child = child.NextSibling) builder.Append(child.GetText()); return builder.ToString(); } /// <summary> /// Removes nodes from start up to but not including the end node. /// Start and end are assumed to have the same parent. /// </summary> private static void RemoveSameParent(Node startNode, Node endNode) { if (endNode != null && startNode.ParentNode != endNode.ParentNode) throw new ArgumentException("Start and end nodes are expected to have the same parent."); Node curChild = startNode; while ((curChild != null) && (curChild != endNode)) { Node nextChild = curChild.NextSibling; curChild.Remove(); curChild = nextChild; } } private readonly Node mFieldStart; private readonly Node mFieldSeparator; private readonly Node mFieldEnd; private bool mIsLocal; private string mTarget; private static readonly Regex gRegex = new Regex( "\\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, found in one of the customers files. "(\\\\l\\s+)?" + // optional \l flag followed by one or more spaces "\"" + // one apostrophe "([^\"]+)" + // one or more chars except apostrophe (hyperlink target) "\"" // one closing apostrophe ); } }