code: public static CmsXmlContent unmarshal(CmsObject cms, CmsResource resource, ServletRequest req)
      throws CmsXmlException, CmsLoaderException, CmsException {
  
          String rootPath = resource.getRootPath();
  
          if (!CmsResourceTypeXmlContent.isXmlContent(resource)) {
              // sanity check: resource must be of type XML content
              throw new CmsXmlException(
                  Messages.get().container(Messages.ERR_XMLCONTENT_INVALID_TYPE_1, cms.getSitePath(resource)));
          }
  
          // try to get the requested content from the current request attribute
          // this is also necessary for historic versions that have been loaded
          CmsXmlContent content = (CmsXmlContent)req.getAttribute(rootPath);
  
          if (content == null) {
              // unmarshal XML structure from the file content
              CmsFile file = resource instanceof CmsFile ? (CmsFile)resource : cms.readFile(resource);
              content = unmarshal(cms, file);
              // store the content as request attribute for future read requests
              req.setAttribute(rootPath, content);
          }
  
          // return the result
          return content;
      }
docs: Factory method to unmarshal (read) a XML content instance from
  a resource, using the request attributes as cache.<p>
  
  @param cms the current OpenCms context object
  @param resource the resource to unmarshal
  @param req the current request
  
  @return the unmarshaled xml content, or null if the given resource was not of type {@link org.opencms.file.types.CmsResourceTypeXmlContent}
  
  @throws CmsException in something goes wrong
  @throws CmsLoaderException if no loader for the given <code>resource</code> type ({@link CmsResource#getTypeId()}) is available
  @throws CmsXmlException if the given <code>resource</code> is not of type xml content