private ViewDefinition readViewDefinition(Element element) {
      String name = element.getAttribute("name");
      Assert.ifEmpty(name, "can`t read view without name");

      String extend = element.getAttribute("extend");
      String file = element.getAttribute("file");

      if (isNoneEmpty(file)) file = fileScope.getRelativePath(file);

      ViewDefinition viewDef = new ViewDefinition(name, file);
      viewDef.setExtend(extend);

      fragmentRefExpressions.forEach(
          x -> {
            XmlUtils.iterateSubElements(
                element, x, e -> viewDef.addFragment(readFragmentReference(e)));
          });

      resourcesRefExpressions.forEach(
          x -> {
            XmlUtils.iterateSubElements(
                element, x, e -> viewDef.addResources(readResourcesReference(e)));
          });

      return viewDef;
    }
  private Document readPageDefinitionFile(String manifestPathOrPath, PageManifestDef pmd) {
    FileScope fileScope = new FileScope(basePath, manifestPathOrPath);

    // prevent cycle import
    if (loadedFiles.contains(fileScope.getFullPath())) return null;

    String filePath = fileScope.getFullPath();
    try {
      InputStream is = FileUtils.openStream(filePath);
      if (is == null)
        throw new JumbleException("Cant open file stream: " + fileScope.getFullPath());

      Document document = documentBuilder.parse(is);
      loadedFiles.add(fileScope.getFullPath());
      new PageManifestReader().read(fileScope, document, pmd);

      return document;
    } catch (FileNotFoundException e) {
      throw new ManifestNotFound("File not found: " + filePath);
    } catch (XPathExpressionException | IOException | SAXException e) {
      throw new PageManifestLoadingException("Cant read file: " + filePath, e);
    }
  }
    private FragmentDef readFragmentDefinition(Element element) {
      String name = element.getAttribute("name");
      Assert.ifEmpty(name, "can`t read resources bundle without name");

      String file = element.getAttribute("file");
      if (isNoneEmpty(file)) file = fileScope.getRelativePath(file);

      Assert.ifEmpty(file, "fragment definition must contain file attribute");

      FragmentDef fragmentDef = new FragmentDef(name, file);

      readFragmentInnerContent(element, fragmentDef);

      return fragmentDef;
    }
    private FragmentReferenceDef readFragmentReference(Element element) {
      String name = element.getAttribute("name");
      Assert.ifEmpty(name, "can`t read fragment without name");

      String file = element.getAttribute("file");
      if (isNoneEmpty(file)) file = fileScope.getRelativePath(file);

      FragmentReferenceDef fragmentDef = new FragmentReferenceDef(name, file);

      String layout = element.getAttribute("layout");
      fragmentDef.setLayout(layout);

      readFragmentInnerContent(element, fragmentDef);

      return fragmentDef;
    }
    public PageManifestDef read(FileScope fileScope, Document document, PageManifestDef pmd)
        throws XPathExpressionException {
      this.fileScope = fileScope;
      XmlUtils.iterateSubElements(
          document, resourcesExpr, e -> pmd.addResourceSet(readResourcesDefinition(e)));
      XmlUtils.iterateSubElements(
          document, fragmentsExpr, e -> pmd.addFragments(readFragmentDefinition(e)));
      XmlUtils.iterateSubElements(document, viewsExpr, e -> pmd.addView(readViewDefinition(e)));

      List<String> imports =
          XmlUtils.getSingleAttrNodes(
              document, importsExpr, "file", "import tag must contain file attribute");

      imports
          .stream()
          .forEach(
              i ->
                  XMLPageManifestLoader.this.readPageDefinitionFile(
                      fileScope.getRelativePath(i), pmd));

      return pmd;
    }