AEM6。 XML导入到JCR(Oak)

时间:2015-04-01 17:09:05

标签: xml cq5 aem jcr jackrabbit

在从CQ5.4到AEM6的迁移站点中,我在将XML数据导入JCR时遇到了问题。

在CQ5.4上,我们使用" Content Loader Tool"(http(s):// [host]:[port] /crx/loader/index.jsp)将xml加载到jcr。 从CQ5.6.1开始,该工具已被弃用并消失。 AEM6也没有它,就像几个crx:Xml *主节点类型一样(crx:XmlCharacterData,crx:XmlDocument,crx:XmlElement,crx:XmlNode)。

我尝试以编程方式重新导入数据,下面是示例groovy脚本

importXML();
def importXML(){
    FileInputStream  inputStream = new FileInputStream("c:/data.xml "); // XML file
    session.importXML("/content/xmlNode", // Destination JCR node
        inputStream ,
        javax.jcr.ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);
    session.save();
}

但是作为导入结果,我丢失了所有兄弟数据。 导入的数据在JCR中的每个层上只有一个节点。 原因是Oak不支持Same Name Siblings(SNS)。

http://docs.adobe.com/docs/en/aem/6-0/deploy/upgrade/introduction-to-oak.html http://jackrabbit.apache.org/oak/docs/differences.html#Same_name_siblings

我不需要支持SNS或crx:Xml *节点类型。 我很高兴为兄弟姐妹(即node_1,node_2)和主节点类型" nt:unstructured"提供唯一生成的名称。 或者任何其他jcr结构,它保留所有从XML导入的数据。

如何将XML数据导入AEM6?请帮帮我。

2 个答案:

答案 0 :(得分:1)

希望这会帮助某人

以下是我使用导入程序完成的方法:

1)这是一个简单的导入类

@Service(value = Importer.class)
@Component
@Property(name = "importer.scheme", value = "importedData", propertyPrivate =true)

public class DataImporter implements Importer {
private final String SOURCE_URL = "http://someserver/data.xml";
private static final Logger LOGGER = LoggerFactory.getLogger(DealerDataImporter.class);

@Override
public void importData(String s, String s2, Resource resource) throws ImportException {

    try {

        URL url = new URL(SOURCE_URL);
        URLConnection connection = url.openConnection();
        Document doc = parseXML(connection.getInputStream());
        NodeList Nodes = doc.getElementsByTagName("retailer");
        for (int i = 0; i < Nodes.getLength(); i++) {
            Element element = (Element) Nodes.item(i);
            String id = element.getElementsByTagName("id").item(0).getTextContent();
            String name = element.getElementsByTagName("display_name").item(0).getTextContent();
            String about = element.getElementsByTagName("about").item(0).getTextContent();
            writeToRepository(id, name, about, resource);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

private void writeToRepository(String id, String name, String about, Resource resource) {

    try {
        javax.jcr.Node parentNode = resource.adaptTo(javax.jcr.Node.class);

        //Say we want this to be a Page node (use NameConstants.NT_PAGE = cq:Page)
        //all of node types can be created this way
        javax.jcr.Node pageNode = JcrUtil.createPath(parentNode.getPath() + "/" + name, NameConstants.NT_PAGE, parentNode.getSession());
        //Page nodes need jcr:content node to hold all teh relevant properties (NameConstants.NN_CONTENT = "jcr:content")
        javax.jcr.Node contentNode = JcrUtil.createPath(pageNode.getPath() + "/" + NameConstants.NN_CONTENT, "cq:PageContent", parentNode.getSession());
        //set some properties
        contentNode.setProperty("about", about);
        contentNode.setProperty("id", id);
        //save session
        parentNode.getSession().save();

    } catch (Exception e1) {
        e1.printStackTrace();
    } 
}
private Document parseXML(InputStream stream){...}
}

2)然后在 / etc / importers / polling 下的CRXde中添加 sling:Folder 类型的新节点并添加一些属性:

a)target [String]这是一个存储库资源的路径,该资源将被解析为您的Importer类。

b)source [String]如果您正在寻找从多个xml文件导入的话 重要的是,值需要启动importedData(作为它们链接的类中的属性),然后是:SOME_VALIABLE这是上面示例中的s2变量。

c)interval [Long]运行Importer的频率

d)添加一个mixin jcr:mixinTypes类型cq:PollConfig

这应该是它,到目前为止我能够使用这种技术导入任何数据

答案 1 :(得分:0)

不幸的是,看起来不存在自动创建唯一节点的能力(例如,JcrUtils具有createUnique方法,该方法将数字附加到冲突的节点名称)。可以使用XSLT重命名每个节点,使其唯一。