Get description, comments in plain text

Hi,

Does anyone have any idea how can we get descriptions and comments as plain text in issues?

Thanks

Hi @HarshModhiya,

Have you tried version 2 Get issue REST API?

GET /rest/api/2/issue/{issueKeyOrId}?fields=comment,description

If this does not suit your needs, can you share the API you are currently using as well as the response format you are looking for?

Cheers,
Ian

Hi @iragudo ,

I am using /rest/agile/1.0/board/{boardid}/issue API and got comment and description in ADF format but I want only plain text without any formatting.

Thanks,
Harsh

Hi @HarshModhiya ,

You can extract plain text from ADF by mapping through it and looking at all nodes marked text. For an example on how to do that, see: Is it posible to get the body comment as plain text - #16 by AveryLane

1 Like

Hi @mventnor ,

Thanks for your quick suggestion.
As I can see this is a scripting method. Do we have any method available for C#?

Thanks,
Harsh

Hi @HarshModhiya,
I am the one that originally wrote the script that @mventnor linked to. Here is an example in .NET 5.0 that uses the Newtonsoft.Json package (v13.03) to parse the JSON then extract all of the text nodes.

using System;
using System.Collections.Generic;
using Newtonsoft.Json.Linq;

class Program
{
    static void Main(string[] args)
    {
        string jsonString = @"
            {
              ""version"": 1,
              ""type"": ""doc"",
              ""content"": [
                {
                  ""type"": ""heading"",
                  ""attrs"": {
                    ""level"": 1
                  },
                  ""content"": [
                    {
                      ""type"": ""text"",
                      ""text"": ""Lorem""
                    }
                  ]
                },
                {
                  ""type"": ""paragraph"",
                  ""content"": [
                    {
                      ""type"": ""text"",
                      ""text"": ""Lorem ""
                    },
                    {
                      ""type"": ""text"",
                      ""text"": ""ipsum"",
                      ""marks"": [
                        {
                          ""type"": ""strong""
                        }
                      ]
                    },
                    {
                      ""type"": ""text"",
                      ""text"": "" dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris ""
                    },
                    {
                      ""type"": ""text"",
                      ""text"": ""nisi ut aliquip ex ea commodo"",
                      ""marks"": [
                        {
                          ""type"": ""em""
                        },
                        {
                          ""type"": ""underline""
                        }
                      ]
                    },
                    {
                      ""type"": ""text"",
                      ""text"": "" consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. ""
                    }
                  ]
                },
                {
                  ""type"": ""paragraph"",
                  ""content"": [
                    {
                      ""type"": ""text"",
                      ""text"": ""Excepteur sint occaecat cupidatat non proident, ""
                    },
                    {
                      ""type"": ""text"",
                      ""text"": ""sunt in culpa qui officia"",
                      ""marks"": [
                        {
                          ""type"": ""em""
                        }
                      ]
                    },
                    {
                      ""type"": ""text"",
                      ""text"": "" deserunt mollit anim id est laborum.""
                    }
                  ]
                },
                {
                  ""type"": ""bulletList"",
                  ""content"": [
                    {
                      ""type"": ""listItem"",
                      ""content"": [
                        {
                          ""type"": ""paragraph"",
                          ""content"": [
                            {
                              ""type"": ""text"",
                              ""text"": ""Sed ""
                            }
                          ]
                        }
                      ]
                    },
                    {
                      ""type"": ""listItem"",
                      ""content"": [
                        {
                          ""type"": ""paragraph"",
                          ""content"": [
                            {
                              ""type"": ""text"",
                              ""text"": ""ut ""
                            },
                            {
                              ""type"": ""text"",
                              ""text"": ""unde"",
                              ""marks"": [
                                {
                                  ""type"": ""strong""
                                },
                                {
                                  ""type"": ""textColor"",
                                  ""attrs"": {
                                    ""color"": ""#bf2600""
                                  }
                                }
                              ]
                            }
                          ]
                        }
                      ]
                    },
                    {
                      ""type"": ""listItem"",
                      ""content"": [
                        {
                          ""type"": ""paragraph"",
                          ""content"": [
                            {
                              ""type"": ""text"",
                              ""text"": ""perspiciatis ""
                            }
                          ]
                        }
                      ]
                    }
                  ]
                },
                {
                  ""type"": ""paragraph"",
                  ""content"": []
                },
                {
                  ""type"": ""paragraph"",
                  ""content"": []
                }
              ]
            }";

        // Parse the JSON string
        JObject jsonObject = JObject.Parse(jsonString);
		// Extract the text nodes recursively
		List<string> textNodes = ExtractTextNodes(jsonObject);

		// Print the text nodes to the console
		foreach (string textNode in textNodes)
		{
			Console.WriteLine(textNode);
		}
	}

	static List<string> ExtractTextNodes(JToken token)
	{
		List<string> textNodes = new List<string>();

		if (token.Type == JTokenType.Object)
		{
			foreach (JProperty property in token.Children<JProperty>())
			{
				textNodes.AddRange(ExtractTextNodes(property.Value));
			}
		}
		else if (token.Type == JTokenType.Array)
		{
			foreach (JToken value in token.Children())
			{
				textNodes.AddRange(ExtractTextNodes(value));
			}
		}
		else if (token.Type == JTokenType.Property)
		{
			JProperty property = (JProperty)token;
			textNodes.AddRange(ExtractTextNodes(property.Value));
		}
		else if (token.Type == JTokenType.String && token.Parent != null && token.Parent.Type == JTokenType.Property && ((JProperty)token.Parent).Name == "text")
		{
			textNodes.Add(token.ToString());
		}

		return textNodes;
	}
}

Here is the output that is produced:

Lorem
Lorem 
ipsum
 dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris 
nisi ut aliquip ex ea commodo
 consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. 
Excepteur sint occaecat cupidatat non proident, 
sunt in culpa qui officia
 deserunt mollit anim id est laborum.
Sed 
ut 
unde
perspiciatis 

Here is a brief explanation of the program:

  1. The jsonString string is parsed into a JObject using the JObject.Parse method. This creates an in-memory representation of the JSON document that we can manipulate and query in the rest of the program.
  2. The ExtractTextNodes method is called, passing the parsed JObject as a parameter. This method is defined to recursively traverse the JSON structure and collect all “text” node values into a List<string>.This method uses pattern matching on the type of each JToken it encounters during its traversal:
  • If the token is a JObject (i.e., a JSON object), it extracts all of its properties and recursively calls ExtractTextNodes on each property’s value.
  • If the token is a JArray (i.e., a JSON array), it recursively calls ExtractTextNodes on each of its children.
  • If the token is a JProperty (i.e., a JSON key-value pair), it recursively calls ExtractTextNodes on the property’s value.
  • If the token is a JValue of type string and its parent is a JProperty with the name “text”, it adds the string value of the token to the list of text nodes. This is the base case for the recursion, meaning the point at which it stops calling itself and starts returning results.
  1. The text nodes extracted from the JSON string are then printed out to the console.

I am not as familiar with C# so this wasn’t as thoroughly tested as the original Javascript that I wrote but hopefully it is enough of a starting point for you to write your own class definition in C# to suite your specific needs.

3 Likes