Isolate Text String

I have the extracted the below XPath from a website and I need to isolate one of the "NAME" parts. I've been playing around with "Search and Replace" and Regex but I'm unable to find solution. Any pros out there? :slight_smile:

{
"doc": {
"URL": "https://outlook.office.com/people/",
"title": "Personer – xxx – Outlook"
},
"anchor": {
"name": "#document",
"text": ""
},
"xpath": "//*[@id="app"]/div/div[2]/div/div[3]/div/div[2]/div/div[3]/div/div/div/div/div[1]/header/div[2]/div[2]/div[1]/div",
"firstOnly": true,
"matches": [
{
"name": "DIV",
"text": "NAME",
"data-log-name": "PersonName",
"title": "NAME",
"class": "_3amnw _3v9gP css-293"
}
]
}

Here's my try.

The regex I'm using is this:

(?s)\{\R"name": "DIV",\R"text": "(.+?)",\R"data-log-name": "PersonName",\R"title": "(.+?)",

It pulls out both of the NAME parts but you can easily ignore one or other.

This is the test macro I used it in:

The NAME parts are extracted to the local variables LocalVar1 and LocalVar2.

Here's the test macro itself:
Test extract parts of Xpath result.kmmacros (4.0 KB)

Hope that helps.

1 Like

Looks great! Don't seem to be able download the macro though or is it just me?

Oh - just edited the post and re-inserted the macro - should be OK now.

KM has two kinds of built-in JSON-reading capacities:

  • Dictionary actions
  • JSON.parse in Execute a JS for Automation actions.

(Trying to use a regex may risk just complicating things, the Kleene algebra underlying the regex formalism doesn't have a model for recursive patterns like nested brackets, so the combination of JSON and regex will tend to be a recipe for a bit of a headache, sooner or later)

If you wanted to let the KM Dictionary actions pick out different parts of your JSON string, you could try an approach like this:

Read an element from a JSON string with a dictionary and sub-dictionaries.kmmacros (19.6 KB)

1 Like

Looks interesting. But when I run your macro it returns #document instead of NAME?

Maybe because it looks up "name" instead of "title"? I couldn't make it work myself though...

That was a dictionary example of the route through 'anchor' to the value of anchor.name.

I mentioned above that we can also use JSON.parse, and that may sometimes be more flexible:

For a route to:

  • The value paired with "title",
  • in the first (index 0) dictionary of the list paired with "matches"
  • at the top level of your JSON dictionary:

We could write in an Execute JS action:

const 
    dictJSON = JSON.parse(
        Application('Keyboard Maestro Engine')
        .getvariable('dictJSON')
    );
return dictJSON.matches[0].title;

As in:
JSON.parse route to a part of a JSON string.kmmacros (19.0 KB)

1 Like

That's infinitely more simple! I already managed to use it in another situation with a similar problem. Thanks a lot.

1 Like

There is so much to learn. Thanks for showing us that and explaining it :+1:

2 Likes