Unlink Hyperlink does not work on all links

good day,
Unlink Hyperlink does not work on all links. I have a more complex document and in section 17, after this code, the links do not change to plain text.

doc.Range.Fields.Cast<Field>().Where(f => f.Type == targetFieldType).ToList().ForEach(f => f.Unlink());

Could you take a look at it for me, what could it be?

Thank you in advance.

TB

@benestom can you please attach your input and expected output documents for test purposes.

good day,
so that you don’t have to work with the entire document, I’m only sending a part of it.
T.Doc.docx (30.2 KB)

targetFieldType = FieldType.FieldHyperlinkAfterUnlinkCorect.jpg (62.9 KB)
After unlink the text looks like a link :frowning:

1 Like

@benestom Thank you for providing additional information. It’s important to note that the Unlink method in Aspose.Words only replaces the field with its value and does not modify any other properties of the resulting value. Therefore, when you remove a link, you need to specify the font color and underline properties just as you would when inserting a link using the Aspose.Words API.

To achieve the expected output, please review the following code snippet:

Document doc = new Document(@"C:\\Temp\\input.docx");
var hyperlinks = doc.Range.Fields.Where(f => f.Type == Aspose.Words.Fields.FieldType.FieldHyperlink);
foreach(var h in hyperlinks)
{
   UnStyleHyperlink(h);
   h.Unlink();
}
doc.Save(@"C:\\Temp\\output.docx");
private static void UnStyleHyperlink(Field hyperlink)
{
    var run = hyperlink.Start.ParentParagraph.ChildNodes.First(n => n.NodeType == NodeType.Run);
    var color = run == null ? Color.Black : ((Run)run).Font.Color;
    var underline = run == null ? Underline.None : ((Run)run).Font.Underline;
    var separator = hyperlink.Separator;
    var nextSibling = separator.NextSibling;
    while(nextSibling != null && !(nextSibling is FieldEnd)) {
        if(nextSibling.NodeType == NodeType.Run)
        {
            ((Run)nextSibling).Font.Color = color;
            ((Run)nextSibling).Font.Underline = underline;
        }

        nextSibling = nextSibling.NextSibling;
    }
}

Good work, thank you

2 Likes

I found a document that didn’t work. Could you take a look at how to remove the link (blue underlined)…tnpIn.docx (27.3 KB)

1 Like

@benestom Sorry for any inconvenience caused. It’s important to note that creating a generic solution that works in every case can be quite challenging. However, I have made some modifications to the solution to better align with your expected output. Please try using this updated version:

Document doc = new Document(@"C:\\Temp\\input1.docx");
var hyperlinks = doc.Range.Fields.Where(f => f.Type == Aspose.Words.Fields.FieldType.FieldHyperlink);
foreach (var h in hyperlinks)
{
    UnStyleHyperlink(h);
    h.Unlink();
}
doc.Save(@"C:\\Temp\\output1.docx");
private static void UnStyleHyperlink(Field hyperlink)
{
    // Get prev or next Run to keep the same style in paragraph 
    var run = GetPrevRun(hyperlink.Start);
    if (run == null)
    {
        run = GetNextRun(hyperlink.End);
    }

    var color = run == null ? Color.Black : run.Font.Color;
    var underline = run == null ? Underline.None : run.Font.Underline;

    var separator = hyperlink.Separator;
    var nextSibling = separator.NextSibling;
    while (nextSibling != null && !(nextSibling is FieldEnd))
    {
        if (nextSibling.NodeType == NodeType.Run)
        {
            ((Run)nextSibling).Font.Color = color;
            ((Run)nextSibling).Font.Underline = underline;
        }

        nextSibling = nextSibling.NextSibling;
    }
}

private static Run GetPrevRun(Node startNode)
{
    var prevNode = startNode.PreviousSibling;
    while(prevNode != null && prevNode.NodeType != NodeType.Run)
    {
        prevNode = prevNode.PreviousSibling;
    }

    return (Run)prevNode;
}

private static Run GetNextRun(Node startNode)
{
    var nextNode= startNode.NextSibling;
    while (nextNode!= null && nextNode.NodeType != NodeType.Run)
    {
        nextNode= nextNode.NextSibling;
    }

    return (Run)nextNode;
}

output.zip (53.6 KB)

Let me know if you have any further questions or need additional assistance.

Thank you in advance. would it be possible to bend the solution so that it also works on two hypertexts next to each other?
See example:
Input.docx (31.9 KB)
Problem with this:
twoLinkNext.png (1.6 KB)

1 Like

@benestom Please use the code below to skip hyperlinks. This approach can also be used to skip other types of fields:

...
private static Run GetPrevRun(Node startNode)
{
    var prevNode = startNode.PreviousSibling;
    while(prevNode != null && prevNode.NodeType != NodeType.Run)
    {
        if (prevNode.NodeType == NodeType.FieldEnd && ((FieldEnd)prevNode).FieldType == FieldType.FieldHyperlink)
        {
            prevNode = SkipField((FieldEnd)prevNode);
        }
        else
        {
            prevNode = prevNode.PreviousSibling;
        }
    }

    return (Run)prevNode;
}

private static Run GetNextRun(Node startNode)
{
    var nextNode = startNode.NextSibling;

    while (nextNode != null && nextNode.NodeType != NodeType.Run)
    {
        if(nextNode.NodeType == NodeType.FieldStart && ((FieldStart)nextNode).FieldType == FieldType.FieldHyperlink)
        {
            nextNode = SkipField((FieldStart)nextNode);
        }
        else
        {
            nextNode = nextNode.NextSibling;
        }
    }

    return (Run)nextNode;
}

private static Node SkipField(FieldStart fieldStart)
{
    var nextNode = fieldStart.NextSibling;
    while(nextNode != null && nextNode.NodeType != NodeType.FieldEnd)
    {
        nextNode = (nextNode.NextSibling);
    }

    return nextNode;
}

private static Node SkipField(FieldEnd fieldEnd)
{
    var prevNode = fieldEnd.PreviousSibling;
    while (prevNode != null && prevNode.NodeType != NodeType.FieldStart)
    {
        prevNode = (prevNode.PreviousSibling);
    }

    return prevNode;
}