All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.tika.parser.xml.XMLProfiler Maven / Gradle / Ivy

There is a newer version: 2024.11.18598.20241113T125352Z-241000
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.tika.parser.xml;

import org.apache.commons.io.input.CloseShieldInputStream;
import org.apache.tika.exception.TikaException;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.metadata.Property;
import org.apache.tika.mime.MediaType;
import org.apache.tika.parser.AbstractParser;
import org.apache.tika.parser.ParseContext;
import org.apache.tika.sax.OfflineContentHandler;
import org.apache.tika.utils.XMLReaderUtils;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;


/**
 * 

* * This parser enables profiling of XML. It captures the root entity as well as * entity uris/namespaces and entity local names in parallel arrays. *

*

* * This parser is not part of the default set of parsers and must be "turned on" * via a tika config: * * <properties> * <parsers> * <parser class="org.apache.tika.parser.DefaultParser"/> * <parser class="org.apache.tika.parser.xml.XMLProfiler"/> * </parsers> * </properties> *

*

* This was initially designed to profile xmp and xfa in PDFs. Further * work would need to be done to extract other types of xml and/or * xmp in other file formats. Please open a ticket. *

*/ public class XMLProfiler extends AbstractParser { public static Property ROOT_ENTITY = Property.internalText("xmlprofiler:root_entity"); public static Property ENTITY_URIS = Property.internalTextBag("xmlprofiler:entity_uris"); public static Property ENTITY_LOCAL_NAMES = Property.internalTextBag("xmlprofiler:entity_local_names"); private static final Set SUPPORTED_TYPES = Collections.unmodifiableSet(new HashSet<>(Arrays.asList( MediaType.application("xml"), //https://wwwimages2.adobe.com/content/dam/acom/en/devnet/xmp/pdfs/XMP%20SDK%20Release%20cc-2016-08/XMPSpecificationPart3.pdf //"If a MIME type is needed, use application/rdf+xml." MediaType.application("rdf+xml"),//xmp //xfa: https://en.wikipedia.org/wiki/XFA MediaType.application("vnd.adobe.xdp+xml") ))); @Override public Set getSupportedTypes(ParseContext context) { return SUPPORTED_TYPES; } @Override public void parse(InputStream stream, ContentHandler handler, Metadata metadata, ParseContext context) throws IOException, SAXException, TikaException { XMLReaderUtils.parseSAX( new CloseShieldInputStream(stream), new OfflineContentHandler(new XMLProfileHandler(metadata)), context); } private static class XMLProfileHandler extends DefaultHandler { private final Metadata metadata; int starts = 0; Map entities = new TreeMap<>(); public XMLProfileHandler(Metadata metadata) { this.metadata = metadata; } @Override public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException { if (starts == 0) { metadata.set(ROOT_ENTITY, qName); } Set localNames = entities.get(uri); if (localNames == null) { localNames = new TreeSet<>(); entities.put(uri, localNames); } localNames.add(localName); starts++; } @Override public void endDocument() throws SAXException { String[] uris = new String[entities.size()]; String[] localNames = new String[entities.size()]; int i = 0; for (Map.Entry e : entities.entrySet()) { uris[i] = e.getKey(); localNames[i] = joinWith(" ", e.getValue()); i++; } metadata.set(ENTITY_URIS, uris); metadata.set(ENTITY_LOCAL_NAMES, localNames); } static String joinWith(String delimiter, Collection strings) { StringBuilder sb = new StringBuilder(); int i = 0; for (String s : strings) { if (i > 0) { sb.append(delimiter); } sb.append(s); i++; } return sb.toString(); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy