diff --git a/src/Hook/ViewsXmlBackendHooks.php b/src/Hook/ViewsXmlBackendHooks.php
new file mode 100644
index 0000000..9b10ec9
--- /dev/null
+++ b/src/Hook/ViewsXmlBackendHooks.php
@@ -0,0 +1,36 @@
+<?php
+
+namespace Drupal\views_xml_backend\Hook;
+
+use Drupal\Core\Site\Settings;
+use Drupal\views_xml_backend\Plugin\views\query\Xml;
+use Drupal\Core\Hook\Attribute\Hook;
+/**
+ * Hook implementations for views_xml_backend.
+ */
+class ViewsXmlBackendHooks
+{
+    /**
+     * Implements hook_cron().
+     */
+    #[Hook('cron')]
+    public function cron()
+    {
+        // Find old cache files and delete them. Default to one week.
+        $expiration = \Drupal\Core\Site\Settings::get('views_xml_backend_expire', 604800);
+        $directory = \Drupal\Core\Site\Settings::get('views_xml_backend_cache_directory', \Drupal\views_xml_backend\Plugin\views\query\Xml::DEFAULT_CACHE_DIR);
+        $file_system = \Drupal::service('file_system');
+        if (!is_dir($directory)) {
+            return;
+        }
+        // Cache files are sha256 hashes without an extension.
+        foreach ($file_system->scanDirectory($directory, '/^[a-z0-9]+$/') as $file) {
+            if (!$mtime = filemtime($file->uri)) {
+                continue;
+            }
+            if ($mtime < \Drupal::time()->getRequestTime() - $expiration) {
+                $file_system->unlink($file->uri);
+            }
+        }
+    }
+}
diff --git a/src/Hook/ViewsXmlBackendViewsHooks.php b/src/Hook/ViewsXmlBackendViewsHooks.php
new file mode 100644
index 0000000..882d110
--- /dev/null
+++ b/src/Hook/ViewsXmlBackendViewsHooks.php
@@ -0,0 +1,116 @@
+<?php
+
+namespace Drupal\views_xml_backend\Hook;
+
+use Drupal\Core\Hook\Attribute\Hook;
+use Drupal\Core\StringTranslation\StringTranslationTrait;
+/**
+ * Hook implementations for views_xml_backend.
+ */
+class ViewsXmlBackendViewsHooks
+{
+    use StringTranslationTrait;
+    /**
+     * @file
+     * Views hooks for views_xml_backend.
+     */
+    /**
+     * Implements hook_views_data().
+     */
+    #[Hook('views_data')]
+    public function viewsData()
+    {
+        $data = [
+        ];
+        $data['views_xml_backend']['table']['group'] = $this->t('XML');
+        $data['views_xml_backend']['table']['base'] = [
+            'title' => $this->t('XML'),
+            'help' => $this->t('Queries an XML file.'),
+            'query_id' => 'views_xml_backend',
+        ];
+        $data['views_xml_backend']['text'] = [
+            'title' => $this->t('XML Text'),
+            'help' => $this->t('Text in the XML file.'),
+            'field' => [
+                'id' => 'views_xml_backend_standard',
+            ],
+            'argument' => [
+                'id' => 'views_xml_backend_standard',
+            ],
+            'filter' => [
+                'id' => 'views_xml_backend_standard',
+            ],
+            'sort' => [
+                'id' => 'views_xml_backend_standard',
+            ],
+        ];
+        $data['views_xml_backend']['numeric'] = [
+            'title' => $this->t('XML Number'),
+            'help' => $this->t('A numeric value in the XML file.'),
+            'field' => [
+                'id' => 'views_xml_backend_standard',
+            ],
+            'argument' => [
+                'id' => 'views_xml_backend_numeric',
+            ],
+            'filter' => [
+                'id' => 'views_xml_backend_numeric',
+            ],
+            'sort' => [
+                'id' => 'views_xml_backend_numeric',
+            ],
+        ];
+        $data['views_xml_backend']['date'] = [
+            'title' => $this->t('XML Date'),
+            'help' => $this->t('Date in the XML file.'),
+            'field' => [
+                'id' => 'views_xml_backend_date',
+            ],
+            'argument' => [
+                'id' => 'views_xml_backend_date',
+            ],
+            'filter' => [
+                'id' => 'views_xml_backend_date',
+            ],
+            'sort' => [
+                'id' => 'views_xml_backend_date',
+            ],
+        ];
+        $data['views_xml_backend']['date_year'] = [
+            'title' => $this->t('XML Year'),
+            'help' => $this->t('Year in the XML file.'),
+            'argument' => [
+                'id' => 'views_xml_backend_date_year',
+            ],
+        ];
+        $data['views_xml_backend']['date_month'] = [
+            'title' => $this->t('XML Month'),
+            'help' => $this->t('Month in the XML file.'),
+            'argument' => [
+                'id' => 'views_xml_backend_date_month',
+            ],
+        ];
+        $data['views_xml_backend']['date_day'] = [
+            'title' => $this->t('XML Day'),
+            'help' => $this->t('Day in the XML file.'),
+            'argument' => [
+                'id' => 'views_xml_backend_date_day',
+            ],
+        ];
+        $data['views_xml_backend']['markup'] = [
+            'title' => $this->t('HTML Markup'),
+            'help' => $this->t('HTML text in the XML file.'),
+            'field' => [
+                'id' => 'views_xml_backend_markup',
+            ],
+        ];
+        $data['views_xml_backend']['passthrough'] = [
+            'title' => $this->t('Pass through'),
+            'help' => $this->t('This argument handler does not filter any values. It can be used to pass in values from an argument into token replacements.'),
+            'argument' => [
+                'id' => 'views_xml_backend_passthrough',
+            ],
+        ];
+        return $data;
+    }
+}
diff --git a/src/Plugin/views/field/Markup.php b/src/Plugin/views/field/Markup.php
index 3deb295..0577c56 100644
--- a/src/Plugin/views/field/Markup.php
+++ b/src/Plugin/views/field/Markup.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\views_xml_backend\Plugin\views\field;
 
+use Drupal\Component\Utility\DeprecationHelper;
+use Drupal\filter\FilterFormatRepositoryInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Render\RendererInterface;
 use Drupal\Core\Session\AccountProxyInterface;
@@ -74,7 +76,7 @@ class Markup extends Standard {
     parent::buildOptionsForm($form, $form_state);
 
     $options = [];
-    foreach (filter_formats($this->currentUser) as $id => $format) {
+    foreach (DeprecationHelper::backwardsCompatibleCall(\Drupal::VERSION, '11.4.0', fn() => \Drupal::service(FilterFormatRepositoryInterface::class)->getFormatsForAccount($this->currentUser), fn() => filter_formats($this->currentUser)) as $id => $format) {
       $options[$id] = $format->get('name');
     }
 
@@ -102,7 +104,7 @@ class Markup extends Standard {
       '#langcode' => '',
     ];
 
-    return $this->renderer->renderPlain($build);
+    return DeprecationHelper::backwardsCompatibleCall(\Drupal::VERSION, '10.3.0', fn() => $this->renderer->renderInIsolation($build), fn() => $this->renderer->renderPlain($build));
   }
 
 }
diff --git a/src/Plugin/views/query/Xml.php b/src/Plugin/views/query/Xml.php
index abc0393..3c8f14b 100644
--- a/src/Plugin/views/query/Xml.php
+++ b/src/Plugin/views/query/Xml.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\views_xml_backend\Plugin\views\query;
 
+use Drupal\Component\Utility\DeprecationHelper;
+use Drupal\Core\File\FileExists;
 use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\File\FileSystemInterface;
@@ -252,7 +254,7 @@ class Xml extends QueryPluginBase {
    *   The alias used to refer to this specific table, or NULL if the table
    *   cannot be ensured.
    */
-  public function ensureTable($table, $relationship = NULL, JoinPluginBase $join = NULL) {
+  public function ensureTable($table, $relationship = NULL, ?JoinPluginBase $join = NULL) {
     return $table;
   }
 
@@ -710,7 +712,7 @@ class Xml extends QueryPluginBase {
 
     $data = trim($response->getBody());
 
-    $this->fileSystem->saveData($data, $cache_file, FileSystemInterface::EXISTS_REPLACE);
+    $this->fileSystem->saveData($data, $cache_file, DeprecationHelper::backwardsCompatibleCall(\Drupal::VERSION, '10.3.0', fn() => FileExists::Replace, fn() => FileSystemInterface::EXISTS_REPLACE));
     $this->cacheBackend->set($cache_key, array_change_key_case($response->getHeaders()));
 
     return $data;
diff --git a/src/Tests/ViewsXMLBackendAddTest.php b/src/Tests/ViewsXMLBackendAddTest.php
index b414b83..22555f9 100644
--- a/src/Tests/ViewsXMLBackendAddTest.php
+++ b/src/Tests/ViewsXMLBackendAddTest.php
@@ -2,11 +2,16 @@
 
 namespace Drupal\views_xml_backend\Tests;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
+
 /**
  * Tests basic functions from the Views XML Backend module.
  *
  * @group views_xml_backend
  */
+#[Group('views_xml_backend')]
+#[RunTestsInSeparateProcesses]
 class ViewsXMLBackendAddTest extends ViewsXMLBackendBase {
 
   /**
diff --git a/src/Tests/ViewsXMLBackendFilteringTest.php b/src/Tests/ViewsXMLBackendFilteringTest.php
index fc11be6..f756819 100644
--- a/src/Tests/ViewsXMLBackendFilteringTest.php
+++ b/src/Tests/ViewsXMLBackendFilteringTest.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\Tests\views_xml_backend\Functional;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
 use Drupal\views\Entity\View;
 use Drupal\views_xml_backend\Tests\ViewsXMLBackendBase;
 
@@ -10,6 +12,8 @@ use Drupal\views_xml_backend\Tests\ViewsXMLBackendBase;
  *
  * @group views_xml_backend
  */
+#[Group('views_xml_backend')]
+#[RunTestsInSeparateProcesses]
 class ViewsXMLBackendFilteringTest extends ViewsXMLBackendBase {
 
   /**
diff --git a/src/Tests/ViewsXMLBackendPagingTest.php b/src/Tests/ViewsXMLBackendPagingTest.php
index d735030..5bc160c 100644
--- a/src/Tests/ViewsXMLBackendPagingTest.php
+++ b/src/Tests/ViewsXMLBackendPagingTest.php
@@ -2,11 +2,16 @@
 
 namespace Drupal\views_xml_backend\Tests;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
+
 /**
  * Tests paging functions from the Views XML Backend module.
  *
  * @group views_xml_backend
  */
+#[Group('views_xml_backend')]
+#[RunTestsInSeparateProcesses]
 class ViewsXMLBackendPagingTest extends ViewsXMLBackendBase {
 
   /**
diff --git a/src/Tests/ViewsXMLBackendSortingTest.php b/src/Tests/ViewsXMLBackendSortingTest.php
index dd63e4d..ea0be7c 100644
--- a/src/Tests/ViewsXMLBackendSortingTest.php
+++ b/src/Tests/ViewsXMLBackendSortingTest.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\Tests\views_xml_backend\Functional;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
 use Drupal\views\Entity\View;
 use Drupal\views_xml_backend\Tests\ViewsXMLBackendBase;
 
@@ -10,6 +12,8 @@ use Drupal\views_xml_backend\Tests\ViewsXMLBackendBase;
  *
  * @group views_xml_backend
  */
+#[Group('views_xml_backend')]
+#[RunTestsInSeparateProcesses]
 class ViewsXMLBackendSortingTest extends ViewsXMLBackendBase {
 
   /**
diff --git a/tests/src/Unit/ModuleFuncsTest.php b/tests/src/Unit/ModuleFuncsTest.php
index 160cbd4..3b5da75 100644
--- a/tests/src/Unit/ModuleFuncsTest.php
+++ b/tests/src/Unit/ModuleFuncsTest.php
@@ -2,11 +2,14 @@
 
 namespace Drupal\Tests\views_xml_backend\Unit;
 
+use PHPUnit\Framework\Attributes\Group;
+
 /**
  * Module function tests.
  *
  * @group views_xml_backend
  */
+#[Group('views_xml_backend')]
 class ModuleFuncsTest extends ViewsXmlBackendTestBase {
 
   /**
diff --git a/tests/src/Unit/Plugin/views/argument/NumericTest.php b/tests/src/Unit/Plugin/views/argument/NumericTest.php
index 44a4e3b..4cd81b0 100644
--- a/tests/src/Unit/Plugin/views/argument/NumericTest.php
+++ b/tests/src/Unit/Plugin/views/argument/NumericTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\Tests\views_xml_backend\Unit\Plugin\views\argument;
 
+use PHPUnit\Framework\Attributes\Group;
 use Drupal\Tests\views_xml_backend\Unit\ViewsXmlBackendTestBase;
 use Drupal\views_xml_backend\Plugin\views\argument\Numeric;
 
@@ -9,6 +10,7 @@ use Drupal\views_xml_backend\Plugin\views\argument\Numeric;
  * @coversDefaultClass \Drupal\views_xml_backend\Plugin\views\argument\Numeric
  * @group views_xml_backend
  */
+#[Group('views_xml_backend')]
 class NumericTest extends ViewsXmlBackendTestBase {
 
   /**
diff --git a/tests/src/Unit/Plugin/views/argument/StandardTest.php b/tests/src/Unit/Plugin/views/argument/StandardTest.php
index e67daa0..8f0aecf 100644
--- a/tests/src/Unit/Plugin/views/argument/StandardTest.php
+++ b/tests/src/Unit/Plugin/views/argument/StandardTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\Tests\views_xml_backend\Unit\Plugin\views\argument;
 
+use PHPUnit\Framework\Attributes\Group;
 use Drupal\Tests\views_xml_backend\Unit\ViewsXmlBackendTestBase;
 use Drupal\views_xml_backend\Plugin\views\argument\Standard;
 
@@ -9,6 +10,7 @@ use Drupal\views_xml_backend\Plugin\views\argument\Standard;
  * @coversDefaultClass \Drupal\views_xml_backend\Plugin\views\argument\Standard
  * @group views_xml_backend
  */
+#[Group('views_xml_backend')]
 class StandardTest extends ViewsXmlBackendTestBase {
 
   /**
diff --git a/tests/src/Unit/Plugin/views/field/DateTest.php b/tests/src/Unit/Plugin/views/field/DateTest.php
index 2f0e07c..c4a724f 100644
--- a/tests/src/Unit/Plugin/views/field/DateTest.php
+++ b/tests/src/Unit/Plugin/views/field/DateTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\Tests\views_xml_backend\Unit\Plugin\views\field;
 
+use PHPUnit\Framework\Attributes\Group;
 use Drupal\Core\Datetime\DateFormatterInterface;
 use Drupal\Core\Entity\EntityStorageInterface;
 use Drupal\Tests\views_xml_backend\Unit\ViewsXmlBackendTestBase;
@@ -12,6 +13,7 @@ use Prophecy\PhpUnit\ProphecyTrait;
  * @coversDefaultClass \Drupal\views_xml_backend\Plugin\views\field\Date
  * @group views_xml_backend
  */
+#[Group('views_xml_backend')]
 class DateTest extends ViewsXmlBackendTestBase {
 
   use ProphecyTrait;
diff --git a/tests/src/Unit/Plugin/views/field/MarkupTest.php b/tests/src/Unit/Plugin/views/field/MarkupTest.php
index bf09e17..30e8efb 100644
--- a/tests/src/Unit/Plugin/views/field/MarkupTest.php
+++ b/tests/src/Unit/Plugin/views/field/MarkupTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\Tests\views_xml_backend\Unit\Plugin\views\field;
 
+use PHPUnit\Framework\Attributes\Group;
 use Drupal\Core\Render\RendererInterface;
 use Drupal\Core\Session\AccountProxyInterface;
 use Drupal\Tests\views_xml_backend\Unit\ViewsXmlBackendTestBase;
@@ -13,6 +14,7 @@ use Prophecy\PhpUnit\ProphecyTrait;
  * @coversDefaultClass \Drupal\views_xml_backend\Plugin\views\field\Markup
  * @group views_xml_backend
  */
+#[Group('views_xml_backend')]
 class MarkupTest extends ViewsXmlBackendTestBase {
 
   use ProphecyTrait;
diff --git a/tests/src/Unit/Plugin/views/field/StandardTest.php b/tests/src/Unit/Plugin/views/field/StandardTest.php
index dcda469..503e6bb 100644
--- a/tests/src/Unit/Plugin/views/field/StandardTest.php
+++ b/tests/src/Unit/Plugin/views/field/StandardTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\Tests\views_xml_backend\Unit\Plugin\views\field;
 
+use PHPUnit\Framework\Attributes\Group;
 use Drupal\Tests\views_xml_backend\Unit\ViewsXmlBackendTestBase;
 use Drupal\views_xml_backend\Plugin\views\field\Standard;
 use Drupal\views_xml_backend\Plugin\views\query\Xml;
@@ -13,6 +14,7 @@ use Prophecy\PhpUnit\ProphecyTrait;
  * @coversDefaultClass \Drupal\views_xml_backend\Plugin\views\field\Standard
  * @group views_xml_backend
  */
+#[Group('views_xml_backend')]
 class StandardTest extends ViewsXmlBackendTestBase {
 
   use ProphecyTrait;
diff --git a/tests/src/Unit/Plugin/views/filter/NumericTest.php b/tests/src/Unit/Plugin/views/filter/NumericTest.php
index 36a4ff3..4606dcd 100644
--- a/tests/src/Unit/Plugin/views/filter/NumericTest.php
+++ b/tests/src/Unit/Plugin/views/filter/NumericTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\Tests\views_xml_backend\Unit\Plugin\views\filter;
 
+use PHPUnit\Framework\Attributes\Group;
 use Drupal\Tests\views_xml_backend\Unit\ViewsXmlBackendTestBase;
 use Drupal\views_xml_backend\Plugin\views\filter\Numeric;
 
@@ -9,6 +10,7 @@ use Drupal\views_xml_backend\Plugin\views\filter\Numeric;
  * @coversDefaultClass \Drupal\views_xml_backend\Plugin\views\filter\Numeric
  * @group views_xml_backend
  */
+#[Group('views_xml_backend')]
 class NumericTest extends ViewsXmlBackendTestBase {
 
   /**
diff --git a/tests/src/Unit/Plugin/views/filter/StandardTest.php b/tests/src/Unit/Plugin/views/filter/StandardTest.php
index e7d0428..cd15d6e 100644
--- a/tests/src/Unit/Plugin/views/filter/StandardTest.php
+++ b/tests/src/Unit/Plugin/views/filter/StandardTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\Tests\views_xml_backend\Unit\Plugin\views\filter;
 
+use PHPUnit\Framework\Attributes\Group;
 use Drupal\Core\Database\Connection;
 use Drupal\Core\DependencyInjection\ContainerBuilder;
 use Drupal\Tests\views_xml_backend\Unit\ViewsXmlBackendTestBase;
@@ -11,6 +12,7 @@ use Drupal\views_xml_backend\Plugin\views\filter\Standard;
  * @coversDefaultClass \Drupal\views_xml_backend\Plugin\views\filter\Standard
  * @group views_xml_backend
  */
+#[Group('views_xml_backend')]
 class StandardTest extends ViewsXmlBackendTestBase {
 
   /**
diff --git a/tests/src/Unit/Plugin/views/query/XmlTest.php b/tests/src/Unit/Plugin/views/query/XmlTest.php
index a7a9708..28d61ed 100644
--- a/tests/src/Unit/Plugin/views/query/XmlTest.php
+++ b/tests/src/Unit/Plugin/views/query/XmlTest.php
@@ -20,6 +20,7 @@ namespace Drupal\Tests\views_xml_backend\Unit\Plugin\views\query {
    * @coversDefaultClass \Drupal\views_xml_backend\Plugin\views\query\Xml
    * @group views_xml_backend
    */
+  #[\PHPUnit\Framework\Attributes\Group('views_xml_backend')]
   class XmlTest extends ViewsXmlBackendTestBase {
 
     /**
diff --git a/tests/src/Unit/Plugin/views/sort/DateTest.php b/tests/src/Unit/Plugin/views/sort/DateTest.php
index eeaaa3b..33fb8f1 100644
--- a/tests/src/Unit/Plugin/views/sort/DateTest.php
+++ b/tests/src/Unit/Plugin/views/sort/DateTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\Tests\views_xml_backend\Unit\Plugin\views\sort;
 
+use PHPUnit\Framework\Attributes\Group;
 use Drupal\Tests\views_xml_backend\Unit\ViewsXmlBackendTestBase;
 use Drupal\views_xml_backend\Plugin\views\query\Xml;
 use Drupal\views_xml_backend\Plugin\views\sort\Date;
@@ -13,6 +14,7 @@ use Prophecy\PhpUnit\ProphecyTrait;
  * @coversDefaultClass \Drupal\views_xml_backend\Plugin\views\sort\Date
  * @group views_xml_backend
  */
+#[Group('views_xml_backend')]
 class DateTest extends ViewsXmlBackendTestBase {
 
   use ProphecyTrait;
diff --git a/tests/src/Unit/Plugin/views/sort/NumericTest.php b/tests/src/Unit/Plugin/views/sort/NumericTest.php
index 6ce48af..c60cd3c 100644
--- a/tests/src/Unit/Plugin/views/sort/NumericTest.php
+++ b/tests/src/Unit/Plugin/views/sort/NumericTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\Tests\views_xml_backend\Unit\Plugin\views\sort;
 
+use PHPUnit\Framework\Attributes\Group;
 use Drupal\Tests\views_xml_backend\Unit\ViewsXmlBackendTestBase;
 use Drupal\views_xml_backend\Plugin\views\query\Xml;
 use Drupal\views_xml_backend\Plugin\views\sort\Numeric;
@@ -13,6 +14,7 @@ use Prophecy\PhpUnit\ProphecyTrait;
  * @coversDefaultClass \Drupal\views_xml_backend\Plugin\views\sort\Numeric
  * @group views_xml_backend
  */
+#[Group('views_xml_backend')]
 class NumericTest extends ViewsXmlBackendTestBase {
 
   use ProphecyTrait;
diff --git a/tests/src/Unit/Plugin/views/sort/StandardTest.php b/tests/src/Unit/Plugin/views/sort/StandardTest.php
index 88e1f5a..971c16d 100644
--- a/tests/src/Unit/Plugin/views/sort/StandardTest.php
+++ b/tests/src/Unit/Plugin/views/sort/StandardTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\Tests\views_xml_backend\Unit\Plugin\views\sort;
 
+use PHPUnit\Framework\Attributes\Group;
 use Drupal\Tests\views_xml_backend\Unit\ViewsXmlBackendTestBase;
 use Drupal\views_xml_backend\Plugin\views\query\Xml;
 use Drupal\views_xml_backend\Plugin\views\sort\Standard;
@@ -13,6 +14,7 @@ use Prophecy\PhpUnit\ProphecyTrait;
  * @coversDefaultClass \Drupal\views_xml_backend\Plugin\views\sort\Standard
  * @group views_xml_backend
  */
+#[Group('views_xml_backend')]
 class StandardTest extends ViewsXmlBackendTestBase {
 
   use ProphecyTrait;
diff --git a/tests/src/Unit/Sorter/DateSorterTest.php b/tests/src/Unit/Sorter/DateSorterTest.php
index be57e64..9f862bf 100644
--- a/tests/src/Unit/Sorter/DateSorterTest.php
+++ b/tests/src/Unit/Sorter/DateSorterTest.php
@@ -2,12 +2,14 @@
 
 namespace Drupal\Tests\views_xml_backend\Unit\Sorter;
 
+use PHPUnit\Framework\Attributes\Group;
 use Drupal\views_xml_backend\Sorter\DateSorter;
 
 /**
  * @coversDefaultClass \Drupal\Tests\views_xml_backend\Unit\Sorter\DateSorterTest
  * @group views_xml_backend
  */
+#[Group('views_xml_backend')]
 class DateSorterTest extends StringSorterTest {
 
   protected function getSorter($field, $direction) {
diff --git a/tests/src/Unit/Sorter/NumericSorterTest.php b/tests/src/Unit/Sorter/NumericSorterTest.php
index 6a1d818..3ab7d82 100644
--- a/tests/src/Unit/Sorter/NumericSorterTest.php
+++ b/tests/src/Unit/Sorter/NumericSorterTest.php
@@ -2,12 +2,14 @@
 
 namespace Drupal\Tests\views_xml_backend\Unit\Sorter;
 
+use PHPUnit\Framework\Attributes\Group;
 use Drupal\views_xml_backend\Sorter\NumericSorter;
 
 /**
  * @coversDefaultClass \Drupal\Tests\views_xml_backend\Unit\Sorter\NumericSorterTest
  * @group views_xml_backend
  */
+#[Group('views_xml_backend')]
 class NumericSorterTest extends StringSorterTest {
 
   protected function getSorter($field, $direction) {
diff --git a/tests/src/Unit/Sorter/StringSorterTest.php b/tests/src/Unit/Sorter/StringSorterTest.php
index 82ef949..528139f 100644
--- a/tests/src/Unit/Sorter/StringSorterTest.php
+++ b/tests/src/Unit/Sorter/StringSorterTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\Tests\views_xml_backend\Unit\Sorter;
 
+use PHPUnit\Framework\Attributes\Group;
 use Drupal\Tests\views_xml_backend\Unit\ViewsXmlBackendTestBase;
 use Drupal\views\ResultRow;
 use Drupal\views_xml_backend\Sorter\StringSorter;
@@ -10,6 +11,7 @@ use Drupal\views_xml_backend\Sorter\StringSorter;
  * @coversDefaultClass \Drupal\Tests\views_xml_backend\Unit\Sorter\StringSorterTest
  * @group views_xml_backend
  */
+#[Group('views_xml_backend')]
 class StringSorterTest extends ViewsXmlBackendTestBase {
 
   public function testAsc() {
diff --git a/tests/src/Unit/XpathTest.php b/tests/src/Unit/XpathTest.php
index 3abee2e..b2d4aa1 100644
--- a/tests/src/Unit/XpathTest.php
+++ b/tests/src/Unit/XpathTest.php
@@ -2,12 +2,14 @@
 
 namespace Drupal\Tests\views_xml_backend\Unit;
 
+use PHPUnit\Framework\Attributes\Group;
 use Drupal\views_xml_backend\Xpath;
 
 /**
  * @coversDefaultClass \Drupal\views_xml_backend\Xpath
  * @group views_xml_backend
  */
+#[Group('views_xml_backend')]
 class XpathTest extends ViewsXmlBackendTestBase {
 
   /**
diff --git a/views_xml_backend.module b/views_xml_backend.module
index 78d0e65..c23325e 100644
--- a/views_xml_backend.module
+++ b/views_xml_backend.module
@@ -4,33 +4,18 @@
  * @file
  * Hook implementations for views_xml_backend.
  */
-
+use Drupal\Core\Hook\Attribute\LegacyHook;
+use Drupal\views_xml_backend\Hook\ViewsXmlBackendHooks;
 use Drupal\Core\Site\Settings;
 use Drupal\views_xml_backend\Plugin\views\query\Xml;
 
 /**
  * Implements hook_cron().
  */
-function views_xml_backend_cron() {
-  // Find old cache files and delete them. Default to one week.
-  $expiration = Settings::get('views_xml_backend_expire', 604800);
-  $directory = Settings::get('views_xml_backend_cache_directory', Xml::DEFAULT_CACHE_DIR);
-  $file_system = \Drupal::service('file_system');
-
-  if (!is_dir($directory)) {
-    return;
-  }
-
-  // Cache files are sha256 hashes without an extension.
-  foreach ($file_system->scanDirectory($directory, '/^[a-z0-9]+$/') as $file) {
-    if (!$mtime = filemtime($file->uri)) {
-      continue;
-    }
-
-    if ($mtime < \Drupal::time()->getRequestTime() - $expiration) {
-      $file_system->unlink($file->uri);
-    }
-  }
+#[LegacyHook]
+function views_xml_backend_cron()
+{
+    \Drupal::service(ViewsXmlBackendHooks::class)->cron();
 }
 
 /**
diff --git a/views_xml_backend.services.yml b/views_xml_backend.services.yml
index 25200fd..61dad1a 100644
--- a/views_xml_backend.services.yml
+++ b/views_xml_backend.services.yml
@@ -12,3 +12,11 @@ services:
       - { name: cache.bin }
     factory: cache_factory:get
     arguments: [views_xml_backend_download]
+
+  Drupal\views_xml_backend\Hook\ViewsXmlBackendHooks:
+    class: Drupal\views_xml_backend\Hook\ViewsXmlBackendHooks
+    autowire: true
+
+  Drupal\views_xml_backend\Hook\ViewsXmlBackendViewsHooks:
+    class: Drupal\views_xml_backend\Hook\ViewsXmlBackendViewsHooks
+    autowire: true
diff --git a/views_xml_backend.views.inc b/views_xml_backend.views.inc
index 6298551..9f1ad7c 100644
--- a/views_xml_backend.views.inc
+++ b/views_xml_backend.views.inc
@@ -1,79 +1,17 @@
 <?php
 
+use Drupal\Core\Hook\Attribute\LegacyHook;
+use Drupal\views_xml_backend\Hook\ViewsXmlBackendViewsHooks;
+
 /**
  * @file
  * Views hooks for views_xml_backend.
  */
-
 /**
  * Implements hook_views_data().
  */
-function views_xml_backend_views_data() {
-  $data = [];
-  $data['views_xml_backend']['table']['group'] = t('XML');
-
-  $data['views_xml_backend']['table']['base'] = [
-    'title' => t('XML'),
-    'help' => t('Queries an XML file.'),
-    'query_id' => 'views_xml_backend',
-  ];
-
-  $data['views_xml_backend']['text'] = [
-    'title' => t('XML Text'),
-    'help' => t('Text in the XML file.'),
-    'field' => ['id' => 'views_xml_backend_standard'],
-    'argument' => ['id' => 'views_xml_backend_standard'],
-    'filter' => ['id' => 'views_xml_backend_standard'],
-    'sort' => ['id' => 'views_xml_backend_standard'],
-  ];
-
-  $data['views_xml_backend']['numeric'] = [
-    'title' => t('XML Number'),
-    'help' => t('A numeric value in the XML file.'),
-    'field' => ['id' => 'views_xml_backend_standard'],
-    'argument' => ['id' => 'views_xml_backend_numeric'],
-    'filter' => ['id' => 'views_xml_backend_numeric'],
-    'sort' => ['id' => 'views_xml_backend_numeric'],
-  ];
-
-  $data['views_xml_backend']['date'] = [
-    'title' => t('XML Date'),
-    'help' => t('Date in the XML file.'),
-    'field' => ['id' => 'views_xml_backend_date'],
-    'argument' => ['id' => 'views_xml_backend_date'],
-    'filter' => ['id' => 'views_xml_backend_date'],
-    'sort' => ['id' => 'views_xml_backend_date'],
-  ];
-
-  $data['views_xml_backend']['date_year'] = [
-    'title' => t('XML Year'),
-    'help' => t('Year in the XML file.'),
-    'argument' => ['id' => 'views_xml_backend_date_year'],
-  ];
-
-  $data['views_xml_backend']['date_month'] = [
-    'title' => t('XML Month'),
-    'help' => t('Month in the XML file.'),
-    'argument' => ['id' => 'views_xml_backend_date_month'],
-  ];
-
-  $data['views_xml_backend']['date_day'] = [
-    'title' => t('XML Day'),
-    'help' => t('Day in the XML file.'),
-    'argument' => ['id' => 'views_xml_backend_date_day'],
-  ];
-
-  $data['views_xml_backend']['markup'] = [
-    'title' => t('HTML Markup'),
-    'help' => t('HTML text in the XML file.'),
-    'field' => ['id' => 'views_xml_backend_markup'],
-  ];
-
-  $data['views_xml_backend']['passthrough'] = [
-    'title' => t('Pass through'),
-    'help' => t('This argument handler does not filter any values. It can be used to pass in values from an argument into token replacements.'),
-    'argument' => ['id' => 'views_xml_backend_passthrough'],
-  ];
-
-  return $data;
+#[LegacyHook]
+function views_xml_backend_views_data()
+{
+    return \Drupal::service(ViewsXmlBackendViewsHooks::class)->viewsData();
 }
