diff --git a/config/import-control-test.xml b/config/import-control-test.xml
index e93ee85..404af56 100644
--- a/config/import-control-test.xml
+++ b/config/import-control-test.xml
@@ -8,5 +8,7 @@
+
+
diff --git a/config/import-control.xml b/config/import-control.xml
index c2c794a..483abd1 100644
--- a/config/import-control.xml
+++ b/config/import-control.xml
@@ -8,6 +8,7 @@
+
-
\ No newline at end of file
+
diff --git a/config/suppressions.xml b/config/suppressions.xml
index 5f36af0..c5dfa13 100644
--- a/config/suppressions.xml
+++ b/config/suppressions.xml
@@ -4,4 +4,8 @@
"-//Checkstyle//DTD SuppressionFilter Configuration 1.1//EN"
"https://checkstyle.org/dtds/suppressions_1_1.dtd">
-
+
+
+
+
+
diff --git a/pom.xml b/pom.xml
index e9d2f70..c70ee48 100644
--- a/pom.xml
+++ b/pom.xml
@@ -44,6 +44,14 @@
+
+
+
+ com.puppycrawl.tools
+ checkstyle
+ ${checkstyle.version}
+
+
org.openrewrite
diff --git a/src/main/java/org/checkstyle/autofix/parser/CheckstyleReportsParser.java b/src/main/java/org/checkstyle/autofix/parser/CheckstyleReportsParser.java
new file mode 100644
index 0000000..d44865b
--- /dev/null
+++ b/src/main/java/org/checkstyle/autofix/parser/CheckstyleReportsParser.java
@@ -0,0 +1,145 @@
+///////////////////////////////////////////////////////////////////////////////////////////////
+// checkstyle-openrewrite-recipes: Automatically fix Checkstyle violations with OpenRewrite.
+// Copyright (C) 2025 The Checkstyle OpenRewrite Recipes Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+///////////////////////////////////////////////////////////////////////////////////////////////
+
+package org.checkstyle.autofix.parser;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Objects;
+
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.StartElement;
+import javax.xml.stream.events.XMLEvent;
+
+public final class CheckstyleReportsParser {
+
+ private static final String FILE_TAG = "file";
+
+ private static final String ERROR_TAG = "error";
+
+ private static final String FILENAME_ATTR = "name";
+
+ private static final String LINE_ATTR = "line";
+
+ private static final String COLUMN_ATTR = "column";
+
+ private static final String SEVERITY_ATTR = "severity";
+
+ private static final String MESSAGE_ATTR = "message";
+
+ private static final String SOURCE_ATTR = "source";
+
+ private CheckstyleReportsParser() {
+
+ }
+
+ public static List parse(Path xmlPath)
+ throws IOException, XMLStreamException {
+
+ final List result = new ArrayList<>();
+
+ try (InputStream inputStream = new FileInputStream(xmlPath.toFile())) {
+
+ final XMLInputFactory inputFactory = XMLInputFactory.newInstance();
+ final XMLEventReader reader = inputFactory.createXMLEventReader(inputStream);
+
+ try {
+ String filename = null;
+
+ while (reader.hasNext()) {
+ final XMLEvent event = reader.nextEvent();
+ if (event.isStartElement()) {
+ final StartElement startElement = event.asStartElement();
+ final String startElementName = startElement.getName().getLocalPart();
+
+ if (FILE_TAG.equals(startElementName)) {
+ filename = parseFileTag(startElement);
+ }
+ else if (ERROR_TAG.equals(startElementName)) {
+ Objects.requireNonNull(filename, "File name can not be null");
+ result.add(parseErrorTag(startElement, filename));
+ }
+ }
+ }
+ }
+ finally {
+ if (reader != null) {
+ reader.close();
+ }
+ }
+ }
+
+ return result;
+ }
+
+ private static String parseFileTag(StartElement startElement) {
+ String fileName = null;
+ final Iterator attributes = startElement.getAttributes();
+ while (attributes.hasNext()) {
+ final Attribute attribute = attributes.next();
+ if (FILENAME_ATTR.equals(attribute.getName().getLocalPart())) {
+ fileName = attribute.getValue();
+ break;
+ }
+ }
+ return fileName;
+ }
+
+ private static CheckstyleViolation parseErrorTag(StartElement startElement, String filename) {
+ Integer line = null;
+ Integer column = null;
+ String source = null;
+ String message = null;
+ String severity = null;
+ final Iterator attributes = startElement
+ .getAttributes();
+ while (attributes.hasNext()) {
+ final Attribute attribute = attributes.next();
+ final String attrName = attribute.getName().getLocalPart();
+ switch (attrName) {
+ case LINE_ATTR:
+ line = Integer.valueOf(attribute.getValue());
+ break;
+ case COLUMN_ATTR:
+ column = Integer.parseInt(attribute.getValue());
+ break;
+ case SEVERITY_ATTR:
+ severity = attribute.getValue();
+ break;
+ case MESSAGE_ATTR:
+ message = attribute.getValue();
+ break;
+ case SOURCE_ATTR:
+ source = attribute.getValue();
+ break;
+ default:
+ break;
+ }
+ }
+ return new CheckstyleViolation(
+ line, column, severity, source, message, filename);
+
+ }
+}
diff --git a/src/main/java/org/checkstyle/autofix/parser/CheckstyleViolation.java b/src/main/java/org/checkstyle/autofix/parser/CheckstyleViolation.java
new file mode 100644
index 0000000..2b3fc7f
--- /dev/null
+++ b/src/main/java/org/checkstyle/autofix/parser/CheckstyleViolation.java
@@ -0,0 +1,68 @@
+///////////////////////////////////////////////////////////////////////////////////////////////
+// checkstyle-openrewrite-recipes: Automatically fix Checkstyle violations with OpenRewrite.
+// Copyright (C) 2025 The Checkstyle OpenRewrite Recipes Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+///////////////////////////////////////////////////////////////////////////////////////////////
+
+package org.checkstyle.autofix.parser;
+
+public final class CheckstyleViolation {
+
+ private final Integer line;
+
+ private final Integer column;
+
+ private final String severity;
+
+ private final String source;
+
+ private final String message;
+
+ private final String fileName;
+
+ public CheckstyleViolation(Integer line, Integer column,
+ String severity, String source, String message, String fileName) {
+ this.line = line;
+ this.column = column;
+ this.severity = severity;
+ this.source = source;
+ this.message = message;
+ this.fileName = fileName;
+ }
+
+ public int getLine() {
+ return line;
+ }
+
+ public int getColumn() {
+ return column;
+ }
+
+ public String getSource() {
+ return source;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public String getFileName() {
+ return fileName;
+ }
+
+ public String getSeverity() {
+ return severity;
+ }
+
+}
diff --git a/src/main/java/org/checkstyle/autofix/parser/package-info.java b/src/main/java/org/checkstyle/autofix/parser/package-info.java
new file mode 100644
index 0000000..413d9fe
--- /dev/null
+++ b/src/main/java/org/checkstyle/autofix/parser/package-info.java
@@ -0,0 +1,21 @@
+///////////////////////////////////////////////////////////////////////////////////////////////
+// checkstyle-openrewrite-recipes: Automatically fix Checkstyle violations with OpenRewrite.
+// Copyright (C) 2025 The Checkstyle OpenRewrite Recipes Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+///////////////////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Provides classes to parse Checkstyle XML report files.
+ */
+package org.checkstyle.autofix.parser;
diff --git a/src/test/java/org/checkstyle/autofix/parser/CheckstyleReportsParserTest.java b/src/test/java/org/checkstyle/autofix/parser/CheckstyleReportsParserTest.java
new file mode 100644
index 0000000..9371d0d
--- /dev/null
+++ b/src/test/java/org/checkstyle/autofix/parser/CheckstyleReportsParserTest.java
@@ -0,0 +1,75 @@
+///////////////////////////////////////////////////////////////////////////////////////////////
+// checkstyle-openrewrite-recipes: Automatically fix Checkstyle violations with OpenRewrite.
+// Copyright (C) 2025 The Checkstyle OpenRewrite Recipes Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+///////////////////////////////////////////////////////////////////////////////////////////////
+
+package org.checkstyle.autofix.parser;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+import java.nio.file.Path;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.junit.jupiter.api.Test;
+
+public class CheckstyleReportsParserTest {
+
+ private static String getPath(String path) {
+ return "src/test/resources/org/checkstyle/autofix/parser/" + path;
+ }
+
+ @Test
+ public void testParseFromResource() throws Exception {
+ final Path xmlPath = Path.of(getPath("checkstyle-report.xml"));
+ final List records = CheckstyleReportsParser.parse(xmlPath);
+
+ assertNotNull(records);
+ assertEquals(1, records.size());
+
+ final CheckstyleViolation record = records.get(0);
+ assertEquals(42, record.getLine());
+ assertEquals(13, record.getColumn());
+ assertEquals("error", record.getSeverity());
+ assertEquals("Example message", record.getMessage());
+ assertEquals("com.puppycrawl.example.Check", record.getSource());
+ assertEquals("Example.java", record.getFileName());
+ }
+
+ @Test
+ public void testParseMultipleFilesReport() throws Exception {
+ final Path xmlPath = Path.of(getPath("checkstyle-multiple-files.xml"));
+ final List records = CheckstyleReportsParser.parse(xmlPath);
+
+ assertNotNull(records);
+ assertEquals(3, records.size());
+
+ final Map> grouped = records.stream()
+ .collect(Collectors.groupingBy(CheckstyleViolation::getFileName));
+
+ assertEquals(2, grouped.size());
+
+ assertEquals(2, grouped.get("Main.java").size());
+ assertEquals(1, grouped.get("Utils.java").size());
+
+ CheckstyleViolation record = grouped.get("Main.java").get(0);
+ assertEquals("error", record.getSeverity());
+
+ record = grouped.get("Utils.java").get(0);
+ assertEquals("warning", record.getSeverity());
+ }
+}
diff --git a/src/test/resources/org/checkstyle/autofix/parser/checkstyle-multiple-files.xml b/src/test/resources/org/checkstyle/autofix/parser/checkstyle-multiple-files.xml
new file mode 100644
index 0000000..5d953d8
--- /dev/null
+++ b/src/test/resources/org/checkstyle/autofix/parser/checkstyle-multiple-files.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/test/resources/org/checkstyle/autofix/parser/checkstyle-report.xml b/src/test/resources/org/checkstyle/autofix/parser/checkstyle-report.xml
new file mode 100644
index 0000000..d354f6d
--- /dev/null
+++ b/src/test/resources/org/checkstyle/autofix/parser/checkstyle-report.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+