protected void validate(List<Element> children, Set<String> elNames) throws PortalException {

    for (Element el : children) {
      if (el.getName().equals("meta-data")) {
        continue;
      }

      String elName = el.attributeValue("name", StringPool.BLANK);
      String elType = el.attributeValue("type", StringPool.BLANK);

      if (Validator.isNull(elName) || elName.startsWith(JournalStructureConstants.RESERVED)) {

        throw new StructureXsdException();
      } else {
        char[] c = elName.toCharArray();

        for (int i = 0; i < c.length; i++) {
          if ((!Validator.isChar(c[i]))
              && (!Validator.isDigit(c[i]))
              && (c[i] != CharPool.DASH)
              && (c[i] != CharPool.UNDERLINE)) {

            throw new StructureXsdException();
          }
        }

        String completePath = elName;

        Element parent = el.getParent();

        while (!parent.isRootElement()) {
          completePath =
              parent.attributeValue("name", StringPool.BLANK) + StringPool.SLASH + completePath;

          parent = parent.getParent();
        }

        String elNameLowerCase = completePath.toLowerCase();

        if (elNames.contains(elNameLowerCase)) {
          throw new StructureXsdException();
        } else {
          elNames.add(elNameLowerCase);
        }
      }

      if (Validator.isNull(elType)) {
        throw new StructureXsdException();
      }

      validate(el.elements(), elNames);
    }
  }
  private Map<String, String> _getField(Element element, String locale) {
    Map<String, String> field = new HashMap<String, String>();

    List<String> availableLocales = getAvailableLanguageIds();

    if ((locale != null) && !availableLocales.contains(locale)) {
      locale = getDefaultLanguageId();
    }

    locale = HtmlUtil.escapeXPathAttribute(locale);

    String xPathExpression = "meta-data[@locale=".concat(locale).concat("]");

    XPath xPathSelector = SAXReaderUtil.createXPath(xPathExpression);

    Node node = xPathSelector.selectSingleNode(element);

    Element metaDataElement = (Element) node.asXPathResult(node.getParent());

    if (metaDataElement != null) {
      List<Element> childMetaDataElements = metaDataElement.elements();

      for (Element childMetaDataElement : childMetaDataElements) {
        String name = childMetaDataElement.attributeValue("name");
        String value = childMetaDataElement.getText();

        field.put(name, value);
      }
    }

    for (Attribute attribute : element.attributes()) {
      field.put(attribute.getName(), attribute.getValue());
    }

    Element parentElement = element.getParent();

    if (parentElement != null) {
      String parentName = parentElement.attributeValue("name");

      if (Validator.isNotNull(parentName)) {
        field.put(_getPrivateAttributeKey("parentName"), parentName);
      }
    }

    return field;
  }
  protected void importAssetCategory(
      PortletDataContext portletDataContext,
      Map<Long, Long> assetVocabularyPKs,
      Map<Long, Long> assetCategoryPKs,
      Map<String, String> assetCategoryUuids,
      Element assetCategoryElement,
      AssetCategory assetCategory)
      throws Exception {

    long userId = portletDataContext.getUserId(assetCategory.getUserUuid());
    long assetVocabularyId =
        MapUtil.getLong(
            assetVocabularyPKs, assetCategory.getVocabularyId(), assetCategory.getVocabularyId());
    long parentAssetCategoryId =
        MapUtil.getLong(
            assetCategoryPKs,
            assetCategory.getParentCategoryId(),
            assetCategory.getParentCategoryId());

    if ((parentAssetCategoryId != AssetCategoryConstants.DEFAULT_PARENT_CATEGORY_ID)
        && (parentAssetCategoryId == assetCategory.getParentCategoryId())) {

      String path = getAssetCategoryPath(portletDataContext, parentAssetCategoryId);

      AssetCategory parentAssetCategory =
          (AssetCategory) portletDataContext.getZipEntryAsObject(path);

      Node parentCategoryNode =
          assetCategoryElement.getParent().selectSingleNode("./category[@path='" + path + "']");

      if (parentCategoryNode != null) {
        importAssetCategory(
            portletDataContext,
            assetVocabularyPKs,
            assetCategoryPKs,
            assetCategoryUuids,
            (Element) parentCategoryNode,
            parentAssetCategory);

        parentAssetCategoryId =
            MapUtil.getLong(
                assetCategoryPKs,
                assetCategory.getParentCategoryId(),
                assetCategory.getParentCategoryId());
      }
    }

    ServiceContext serviceContext = new ServiceContext();

    serviceContext.setAddGroupPermissions(true);
    serviceContext.setAddGuestPermissions(true);
    serviceContext.setCreateDate(assetCategory.getCreateDate());
    serviceContext.setModifiedDate(assetCategory.getModifiedDate());
    serviceContext.setScopeGroupId(portletDataContext.getScopeGroupId());

    AssetCategory importedAssetCategory = null;

    try {
      if (parentAssetCategoryId != AssetCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {

        AssetCategoryUtil.findByPrimaryKey(parentAssetCategoryId);
      }

      List<Element> propertyElements = assetCategoryElement.elements("property");

      String[] properties = new String[propertyElements.size()];

      for (int i = 0; i < propertyElements.size(); i++) {
        Element propertyElement = propertyElements.get(i);

        String key = propertyElement.attributeValue("key");
        String value = propertyElement.attributeValue("value");

        properties[i] = key.concat(StringPool.COLON).concat(value);
      }

      AssetCategory existingAssetCategory =
          AssetCategoryUtil.fetchByP_N_V(
              parentAssetCategoryId, assetCategory.getName(), assetVocabularyId);

      if (existingAssetCategory == null) {
        serviceContext.setUuid(assetCategory.getUuid());

        importedAssetCategory =
            AssetCategoryLocalServiceUtil.addCategory(
                userId,
                parentAssetCategoryId,
                getAssetCategoryTitleMap(assetCategory),
                assetCategory.getDescriptionMap(),
                assetVocabularyId,
                properties,
                serviceContext);
      } else {
        importedAssetCategory =
            AssetCategoryLocalServiceUtil.updateCategory(
                userId,
                existingAssetCategory.getCategoryId(),
                parentAssetCategoryId,
                getAssetCategoryTitleMap(assetCategory),
                assetCategory.getDescriptionMap(),
                assetVocabularyId,
                properties,
                serviceContext);
      }

      assetCategoryPKs.put(assetCategory.getCategoryId(), importedAssetCategory.getCategoryId());

      assetCategoryUuids.put(assetCategory.getUuid(), importedAssetCategory.getUuid());

      portletDataContext.importPermissions(
          AssetCategory.class,
          assetCategory.getCategoryId(),
          importedAssetCategory.getCategoryId());
    } catch (NoSuchCategoryException nsce) {
      _log.error(
          "Could not find the parent category for category " + assetCategory.getCategoryId());
    }
  }