blob: e6a9c25194c19f8e133c00dbb1eec4ff30eee846 [file] [log] [blame]
/** \file parser_config.hpp .
* 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.
\brief Configuration class for parsers.
-------------------------------------------------------------------------- */
#ifndef UIMA_PARSER_CONFIG_HPP
#define UIMA_PARSER_CONFIG_HPP
// ---------------------------------------------------------------------------
// Includes
// ---------------------------------------------------------------------------
#include "uima/pragmas.hpp" //must be first to surpress warnings
#include <map>
#include <stack>
#include <utility>
#include "uima/typesystem.hpp"
namespace uima {
class TCAS;
class TextAnalysisEngineSpecifier;
/**
* The class ParserConfiguration is used to instruct a parser that puts
* tagged document into a CAS on how to map document information contained
* in tags to annotations and features of annotations.
* This configuration is mainly intended to configure HTML and XML parsers
* but could be used for any format that uses labeled tags and tag attributes
*
* For XML input this configuration object also allows to specify if and how
* multiple documents are delimited within one physical XML file.
* Also the content of certain tags can be excluded from being processed at
* all.
*/
class ParserConfiguration {
public:
ParserConfiguration();
/**
* Initialize this config object from settings specified in
* the parser configuration file.
*
* @param parserConfigFilename file name of the configuration file
* @param cas CAS object defining the types relevant
* for the tag2type mappings
*
* @return UIMA_ERR_NONE if OK
*/
TyErrorId init(icu::UnicodeString const & parserConfigFilename, CAS & cas, ErrorInfo & err);
/**
* Returns the tag that is used to delimit/separate multiple
* logical documents within the same physical file.
* If no such tag is defined - i.e. there is only one document
* per file - an empty string is returned.
*
* Note: This option will always return the empty string for HTML.
*/
icu::UnicodeString const & getDocumentDelimiterTag() const;
/**
* Sets the tag that is used to delimit/separate multiple
* logical documents within the same physical file.
*
* @see getDocumentDelimiterTag
*/
void setDocumentDelimiterTag(icu::UnicodeString const & tag);
/**
* Returns the tags that are to be ignored when parsing an (XML) document.
*
* Only the textual content of tags not included in the returned container
* will be part of the CAS document.
*/
vector<icu::UnicodeString> const & getExcludedTags() const;
/**
* Sets the tags that are to be ignored when parsing an (XML) document.
*
* @see getExcludedTags
*/
void setExcludedTags( vector<icu::UnicodeString> const & tags);
/**
* Returns the type of the annotation that the parser is supposed to
* create for each occurrence of a tag with name <code>tagName</code>.
* If no annotation is to be created for occurrences of this tag
* <code>tagName</code> the return value is an invalid type object.
*
* This function returns the value of getDefaultTypeForTags if no
* explicit mapping has been specified.
*
* Note: The returned Type object will be subsumed by type Annotation.
*
* @param tagName The name of the tag to look up
*
* @return The mapped type for tagName or an invalid type
* if no mapping specified
*
* @see setDefaultTypeForTags
*/
Type getTypeForTag(icu::UnicodeString const & tagName) const;
/**
* Sets the type of the annotation that the parser is supposed to
* create for each occurrence of a tag with name <code>tagName</code>.
*
* @param tagName the name of a tag to map
* @param type a CAS type (must be valid!)
*
* @see getTypeForTag
*/
void setTypeForTag(icu::UnicodeString const & tagName, Type type);
/**
* This option can be used to specify a default mapping in case no
* explicit mapping is available for a tag.
*
* If the default type is set (is valid) getTypeForTag will return
* this default type whenever no explicit mapping is specified.
* In this case every tag will be mapped to some type without
* having to specify many mappings.
*
* Since this default value is optional the result of
* getDefaultTypeForTags() may be invalid.
* In this case some tags are not mapped to types.
*
* @param type The type to use as default mapping type
*
* @see getTypeForTag
* @see getDefaultTypeForTags
*
*/
void setDefaultTypeForTags(Type type);
/**
* @return The default type to use for tags not directly mapped
* by getTypeForTag() (may be invalid if none specified)
*
* @see setDefaultType
*/
Type getDefaultTypeForTags() const;
/**
* This allows to specify a feature where the name of the tag is stored
* for each annotation created by the parser.
* If this feature is invalid the parser will take no action.
*
* @param f The feature where the tag name will stored
* f must be of type string.
* Also f must be appropriate for all types mapped to
* tag.
*
* @see getFeatureForTagName
*/
void setFeatureForTagName(Feature f);
/**
* @return The feature where the name of the tag is stored for each
* annotation created by the parser (may be invalid if none
* specified).
*
* @see setFeatureForTagName
*/
Feature getFeatureForTagName() const;
/**
* For a given tag name and attribute name this function returns an
* annotation type and a feature of that type to which the value
* of the attribute is to be mapped.
*
* The returned type and feature will be invalid if the attribute
* <code>attrName</code> at tag <code>tagName</code> is not to be
* mapped to the CAS.
*
* If the returned type and feature are valid the parser is supposed to
* look for the "last" annotation of the returned type and set the
* value of the returned feature at this annotation to the value of
* the attribute <code>attrName</code>.
*
* Note that the parser does not necessarily have to create an annotation
* of the returned type. This mapping can be used to set features of
* existing annotations: E.g. the attribute "name" of the "meta" tag
* in HTML could be mapped to the feature "DocumentName" of
* type "Document"
*
* The "last" occurrence of an annotation of the returned type is
* determined by starting with the annotation corresponding the current
* tag (if there is one) and searching from there towards the beginning
* of the text. The annotation corresponding the current tag is included
* in the search.
*
* For each occurrence of a tag the parser is supposed to first check
* the function <code>getTypeForTag()</code> and create a corresponding
* annotation if <code>getTypeForTag()</code> returns a valid type.
*
* Only after annotations are created for mapped tags the attributes are
* being mapped to features.
* This execution order guarantees that for tags that are used in
* <code>getTypeForTag()</code> and in <code>getFeatureForAttribute()</code>
* the "last" annotation will be the newly created one.
*
* The returned Type object must be subsumed by type Annotation.
*
* The returnedFeature must be of type string, integer or float.
* A conforming parser is supposed to convert the attribute value
* from it's string representation to an appropriate value before
* setting the feature value.
*
* taph 04.12.2002: There is currently a limitation for returnedFeature
* to be of type string only. This will be removed in the future.
*
* @param tagName The name of the tag to look up
* @param attrName The name of the attribute of tag tagName to look up
* @param returnedType Output param: the type corresponding to tag tagName
* @param returnedFeature Output param: the feature corresponding to attrName
*/
void getFeatureForAttribute(
icu::UnicodeString const & tagName,
icu::UnicodeString const & attrName,
Type & returnedType,
Feature & returnedFeature
) const;
/**
* The break properties that can be specified in getBreakPropertyForTag()
*/
enum EnBreakProperty {
enNoBreak = 0,
enWordBreak = 0x200B,
enSentenceBreak = 0x2029,
enLineBreak = 0x2028,
enParagraphBreak = 0x2029,
enNumberOfBreakProperties = 6
};
/**
* Returns the break property the parser is supposed to
* associate for each occurrence of a tag with name <code>tagName</code>.
*
* You can think of break properties as instructions on how to replace
* a tag with white space content during de-tagging an HTML/XML document.
* - tags with enNoBreak property will be replaced by the empty string
* (e.g. bold &lt;b>F&lt;/b>irst Letter becomes
* First Letter)
* - tags with enWordBreak property will be replaced by a Unicode
* U+200B ZERO WIDTH SPACE (e.g. &lt;label>)
* - tags with enSentenceBreak property will be replaced by a Unicode
* paragraph separator character U+2029 PARAGRAPH SEPARATOR ???
* - tags with enLineBreak property will be replaced by a Unicode
* line separator character U+2028 LINE SEPARATOR
* (e.g. &lt;br> and &lt;li>)
* - tags with enParagraphBreak property will be replaced by a Unicode
* paragraph separator character U+2029 PARAGRAPH SEPARATOR
* (e.g. headings like &lt;h1>)
*
* Note that all break properties only apply to the end tag.
* The begin tag is always replaced by the empty string.
* For HTML tags that don't have a end tag (e.g. &lt;br>, or where the
* end tag is optional (e.g. &lt;li>) the parser should introduce the
* replacement character before the next opening tag that can
* conceptually close the tag (e.g. &lt;li>) or the next end tag that
* closes the tag (e.g. &lt;/li>)
*
* If no explicit break property has been given
* getDefaultBreakProperty() is returned.
*
* @param tagName The name of the tag to look up
*/
EnBreakProperty
getBreakPropertyForTag(icu::UnicodeString const & tagName) const;
/**
* Returns the default break property for tags where no explicit
* break property has been configured.
*/
EnBreakProperty getDefaultBreakProperty() const;
/**
* Sets the default break property for tags where no explicit
* break property has been configured.
*/
void setDefaultBreakProperty(EnBreakProperty enBreakProp);
/**
* Returns the (annotation) type corresponding to a break property.
* The return value may be invalid if no specific type is set.
* If a type is specified a conforming parser is supposed to
* create an annotation of that type for each annotation with a given
* break property (in addition to inserting the corresponding break
* character)
*
* In general this is only usefull for paragraphs.
* For all other break types (especialy tokens and sentences)
* a parser can not and should not directly create the entity
* corresponding to the break (token, sentence) as annotation.
* The reason for this that the parser only knows that
* such an annotation must begin at the position of the begin tag and
* end at the begin tag but not how many entities (tokens, sentences)
* may be spanned by the tag (e.g. an h1 tag).
* In general the parser should not create a few instances of
* annotation types (like tokens or sentences) that are mainly created
* by annotators (like the tokenizer). Instead it should leave traces in
* the text that guide the downstream annotator.
*
* But paragraphs are an exception to this as they should be
* created by the parser and only by the parser. For HTML a tokenizer
* applying plain text paragraph finding heuristics (double newline) would
* produce incorrect results.
* So for HTML it would make sense to specify that tags like &lt;p> and &lt;h1>
* etc. are paragraph break and specify the appropriate paragraph
* type as the value of getTypeForBreakProperty()
* Note that you should not map &lt;p> to a type if you do that otherwise
* two annotations would be created for each &lt;p> tag.
* If this is done then to ensure consistency <em>only</em> the parser
* should create paragraph and no annotator should try to do this.
*/
Type getTypeForBreakProperty(EnBreakProperty enBreakProp) const;
private:
// -----------------------------------------------------------------------
// data structures to store mapping information between XML and UIMA
// map holding information about XML Elements which are mapped to UIMA
// types (new annotations are created for each occurrence of such an element)
typedef map< icu::UnicodeString, Type, less<icu::UnicodeString> >
TyXMLNameToTypeMap;
// map holding information about XML Attributes which are mapped to UIMA
// attributes (UIMA Attributes of existing annotations are set to the values
// of the XML Attributes)
// Since each attribute (XML or UIMA) occurs at a certain anchor
// (XML Element or UIMA Type) we need to store 4 pieces of information
// Since more than one attr can be mapped from the same element we need a vector
typedef struct StFeatureInfo_ {
Type type; // 3: Type for Feature
Feature feature; // 4: Feature
}
StFeatureInfo;
typedef map< icu::UnicodeString, StFeatureInfo, less<icu::UnicodeString> >
TyXMLAttrToFeatureMap;
// actual map from 1: the name of XML Element and
// 2: the XML Attribute name to the rest of the mapping info
typedef map< icu::UnicodeString, TyXMLAttrToFeatureMap, less<icu::UnicodeString> >
TyXMLNameToAttrMap;
// map holding information about XML Elements and their break properties
typedef map< icu::UnicodeString, EnBreakProperty, less<icu::UnicodeString> >
TyXMLNameToBreakMap;
// map holding information about XML Elements and their break properties
typedef map< EnBreakProperty, Type, less<EnBreakProperty> >
TyBreakToTypeMap;
TyXMLNameToTypeMap iv_mapXMLNameToType;
TyXMLNameToAttrMap iv_mapXMLNameToAttr;
TyXMLNameToBreakMap iv_mapXMLNameToBreak;
TyBreakToTypeMap iv_mapBreakToType;
icu::UnicodeString iv_ustrDocumentDelimiterTag;
vector<icu::UnicodeString> iv_vecustrExcludedTags;
EnBreakProperty iv_enDefaultBreakProperty;
Type iv_defaultTypeForTags;
Feature iv_featureForTagName;
}
; /* ParserConfiguration */
} // namespace uima
#endif //UIMA_PARSER_CONFIG_HPP