如何遍历org.eclipse.emf.ecore.resource.Resource对象并提取XML数据
Hey there! Since you've already parsed your XML into an EMF org.eclipse.emf.ecore.resource.Resource object, let's tackle your two questions with practical, EMF-native approaches.
1. 遍历Resource对象
EMF models are tree-structured, so traversing a Resource means navigating through its root elements and their child EObjects. Here are two common, straightforward ways to do this:
1.1 Root Elements + Recursive Traversal
The Resource.getContents() method returns all root-level EObjects from your parsed XML. From there, you can recursively dive into every child EObject, including their attributes and references:
// First, iterate through all root elements in the Resource for (EObject rootElement : yourResource.getContents()) { System.out.println("Root element type: " + rootElement.eClass().getName()); // Recursively traverse all child nodes of this root traverseEObjectTree(rootElement); } // Helper method to recursively walk an EObject's attributes and references private static void traverseEObjectTree(EObject currentObject) { // Iterate through all attributes (maps to XML attributes or text content) for (EAttribute attribute : currentObject.eClass().getEAllAttributes()) { Object attributeValue = currentObject.eGet(attribute); System.out.printf(" Attribute '%s': %s%n", attribute.getName(), attributeValue); } // Iterate through all references (maps to XML child tags) for (EReference reference : currentObject.eClass().getEAllReferences()) { Object referenceValue = currentObject.eGet(reference); // Handle single child objects if (referenceValue instanceof EObject) { EObject childObject = (EObject) referenceValue; System.out.printf(" Reference '%s' (type: %s):%n", reference.getName(), childObject.eClass().getName()); traverseEObjectTree(childObject); } // Handle lists of child objects (e.g., repeated XML tags) else if (referenceValue instanceof List<?>) { List<?> childList = (List<?>) referenceValue; System.out.printf(" Reference list '%s' (size: %d):%n", reference.getName(), childList.size()); for (Object item : childList) { if (item instanceof EObject) { traverseEObjectTree((EObject) item); } } } } }
1.2 Using EMF's TreeIterator
If recursion isn't your style, EMF provides a built-in TreeIterator that handles the traversal for you iteratively:
TreeIterator<EObject> iterator = yourResource.getAllContents(); while (iterator.hasNext()) { EObject eObject = iterator.next(); System.out.println("Visited EObject: " + eObject.eClass().getName()); // Add attribute/reference handling logic here (same as the recursive method) }
2. Extracting XML Data from the Resource
Extracting data depends on your specific Ecore model structure, but there are two reliable approaches: using generated model classes (the easiest option) or EMF's reflective API.
2.1 Using Generated Model Classes (Recommended)
If you've generated Java classes from your Ecore model (right-click the Ecore file → Generate Model Code), you can use type-safe getter methods directly:
// Assume your Ecore model's root element is `Library`, with a `name` attribute and `books` list // Cast the root element to your generated class Library rootLibrary = (Library) yourResource.getContents().get(0); // Extract simple attribute values String libraryName = rootLibrary.getName(); System.out.println("Library Name: " + libraryName); // Extract data from associated child objects for (Book book : rootLibrary.getBooks()) { String bookTitle = book.getTitle(); int publicationYear = book.getPublicationYear(); Author bookAuthor = book.getAuthor(); System.out.printf("Book: %s (%d) by %s%n", bookTitle, publicationYear, bookAuthor.getName()); }
2.2 Using Reflective API (No Generated Code)
If you haven't generated model classes, you can use EMF's reflective methods to access attributes and references by name:
EObject rootElement = yourResource.getContents().get(0); // Extract a single attribute value EAttribute nameAttribute = rootElement.eClass().getEAttribute("name"); if (nameAttribute != null) { String nameValue = (String) rootElement.eGet(nameAttribute); System.out.println("Name: " + nameValue); } // Extract a list of associated child objects EReference booksReference = rootElement.eClass().getEReference("books"); if (booksReference != null) { List<EObject> books = (List<EObject>) rootElement.eGet(booksReference); for (EObject book : books) { EAttribute titleAttr = book.eClass().getEAttribute("title"); String title = (String) book.eGet(titleAttr); System.out.println("Book Title: " + title); } }
内容的提问来源于stack exchange,提问作者Promod Kumar

