MCE Initial Implementation.
Points to note: * Assumes all MCE content to be of 'Ignorable' type. Handling other types needs to be implemented. * Uses the first acceptable choice and parses the content. Skips the others. E.g. assuming v2 and v3 both being acceptable and v3 being newer/better, if the choice for v2 is stored first. v3 is skipped.
This commit is contained in:
parent
08380350f9
commit
41cc5c918e
11 changed files with 136 additions and 7 deletions
|
@ -144,9 +144,12 @@ public:
|
|||
|
||||
// helpers ----------------------------------------------------------------
|
||||
|
||||
/** Returns the identifier of the currently processed element. */
|
||||
/** Returns the identifier of the currently processed element. Ignores MCE elements in stack */
|
||||
sal_Int32 getCurrentElement() const;
|
||||
|
||||
/** Returns the identifier of the currently processed element - Including MCE root elements */
|
||||
sal_Int32 getCurrentElementWithMce() const;
|
||||
|
||||
/** Returns true, if nElement contains the identifier of the currently
|
||||
processed element. */
|
||||
inline bool isCurrentElement( sal_Int32 nElement ) const
|
||||
|
@ -274,4 +277,4 @@ public:
|
|||
|
||||
#endif
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||
|
|
|
@ -79,6 +79,11 @@ public:
|
|||
void parseStream( StorageBase& rStorage, const ::rtl::OUString& rStreamName, bool bCloseStream = false )
|
||||
throw( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException );
|
||||
|
||||
::rtl::OUString getNamespaceURL( const ::rtl::OUString& rPrefix )
|
||||
throw( ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException );
|
||||
|
||||
sal_Int32 getNamespaceId( const ::rtl::OUString& aUrl );
|
||||
|
||||
private:
|
||||
::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastParser >
|
||||
mxParser;
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
#include "oox/core/contexthandler2.hxx"
|
||||
#include "oox/core/fragmenthandler.hxx"
|
||||
#include <vector>
|
||||
|
||||
namespace oox {
|
||||
namespace core {
|
||||
|
@ -39,6 +40,19 @@ namespace core {
|
|||
|
||||
class FragmentHandler2 : public FragmentHandler, public ContextHandler2Helper
|
||||
{
|
||||
private:
|
||||
enum MCE_STATE
|
||||
{
|
||||
MCE_UNUSED,
|
||||
MCE_STARTED,
|
||||
MCE_FOUND_CHOICE
|
||||
};
|
||||
::std::vector<MCE_STATE> aMceState;
|
||||
|
||||
private:
|
||||
bool prepareMceContext( sal_Int32 nElement, const AttributeList& rAttribs );
|
||||
|
||||
|
||||
public:
|
||||
explicit FragmentHandler2(
|
||||
XmlFilterBase& rFilter,
|
||||
|
@ -113,4 +127,4 @@ public:
|
|||
|
||||
#endif
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||
|
|
|
@ -204,6 +204,10 @@ public:
|
|||
*/
|
||||
XmlFilterBase& exportDocumentProperties( ::com::sun::star::uno::Reference< ::com::sun::star::document::XDocumentProperties > xProperties );
|
||||
|
||||
::rtl::OUString getNamespaceURL( const ::rtl::OUString& rPrefix );
|
||||
|
||||
sal_Int32 getNamespaceId( const ::rtl::OUString& rUrl );
|
||||
|
||||
void importDocumentProperties() throw();
|
||||
|
||||
protected:
|
||||
|
|
|
@ -74,11 +74,20 @@ ContextHandler2Helper::~ContextHandler2Helper()
|
|||
{
|
||||
}
|
||||
|
||||
sal_Int32 ContextHandler2Helper::getCurrentElement() const
|
||||
sal_Int32 ContextHandler2Helper::getCurrentElementWithMce() const
|
||||
{
|
||||
return mxContextStack->empty() ? XML_ROOT_CONTEXT : mxContextStack->back().mnElement;
|
||||
}
|
||||
|
||||
sal_Int32 ContextHandler2Helper::getCurrentElement() const
|
||||
{
|
||||
for ( ContextStack::const_reverse_iterator It = mxContextStack->rbegin();
|
||||
It != mxContextStack->rend(); It++ )
|
||||
if( getNamespace( It->mnElement ) != NMSP_mce )
|
||||
return It->mnElement;
|
||||
return XML_ROOT_CONTEXT;
|
||||
}
|
||||
|
||||
sal_Int32 ContextHandler2Helper::getParentElement( sal_Int32 nCountBack ) const
|
||||
{
|
||||
if( (nCountBack < 0) || (mxContextStack->size() < static_cast< size_t >( nCountBack )) )
|
||||
|
@ -118,7 +127,7 @@ void ContextHandler2Helper::implCharacters( const OUString& rChars )
|
|||
void ContextHandler2Helper::implEndElement( sal_Int32 nElement )
|
||||
{
|
||||
(void)nElement; // prevent "unused parameter" warning in product build
|
||||
OSL_ENSURE( getCurrentElement() == nElement, "ContextHandler2Helper::implEndElement - context stack broken" );
|
||||
OSL_ENSURE( getCurrentElementWithMce() == nElement, "ContextHandler2Helper::implEndElement - context stack broken" );
|
||||
if( !mxContextStack->empty() )
|
||||
{
|
||||
// #i76091# process collected characters (calls onCharacters() if needed)
|
||||
|
@ -142,7 +151,7 @@ void ContextHandler2Helper::implStartRecord( sal_Int32 nRecId, SequenceInputStre
|
|||
void ContextHandler2Helper::implEndRecord( sal_Int32 nRecId )
|
||||
{
|
||||
(void)nRecId; // prevent "unused parameter" warning in product build
|
||||
OSL_ENSURE( getCurrentElement() == nRecId, "ContextHandler2Helper::implEndRecord - context stack broken" );
|
||||
OSL_ENSURE( getCurrentElementWithMce() == nRecId, "ContextHandler2Helper::implEndRecord - context stack broken" );
|
||||
if( !mxContextStack->empty() )
|
||||
{
|
||||
onEndRecord();
|
||||
|
|
15
oox/source/core/fastparser.cxx
Normal file → Executable file
15
oox/source/core/fastparser.cxx
Normal file → Executable file
|
@ -130,6 +130,21 @@ void FastParser::parseStream( StorageBase& rStorage, const OUString& rStreamName
|
|||
parseStream( rStorage.openInputStream( rStreamName ), rStreamName, bCloseStream );
|
||||
}
|
||||
|
||||
OUString FastParser::getNamespaceURL( const OUString& rPrefix ) throw( IllegalArgumentException, RuntimeException )
|
||||
{
|
||||
if( !mxParser.is() )
|
||||
throw RuntimeException();
|
||||
return mxParser->getNamespaceURL( rPrefix );
|
||||
}
|
||||
|
||||
sal_Int32 FastParser::getNamespaceId( const OUString& rUrl )
|
||||
{
|
||||
for( NamespaceMap::const_iterator aIt = mrNamespaceMap.begin(), aEnd = mrNamespaceMap.end(); aIt != aEnd; ++aIt )
|
||||
if( rUrl == aIt->second )
|
||||
return aIt->first;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
|
||||
} // namespace core
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
************************************************************************/
|
||||
|
||||
#include "oox/core/fragmenthandler2.hxx"
|
||||
#include "oox/core/xmlfilterbase.hxx"
|
||||
|
||||
namespace oox {
|
||||
namespace core {
|
||||
|
@ -38,6 +39,9 @@ using namespace ::com::sun::star::xml::sax;
|
|||
|
||||
using ::rtl::OUString;
|
||||
|
||||
|
||||
using ::com::sun::star::uno::Sequence;
|
||||
|
||||
// ============================================================================
|
||||
|
||||
FragmentHandler2::FragmentHandler2( XmlFilterBase& rFilter, const OUString& rFragmentPath, bool bEnableTrimSpace ) :
|
||||
|
@ -62,11 +66,58 @@ void SAL_CALL FragmentHandler2::endDocument() throw( SAXException, RuntimeExcept
|
|||
finalizeImport();
|
||||
}
|
||||
|
||||
bool FragmentHandler2::prepareMceContext( sal_Int32 nElement, const AttributeList& rAttribs )
|
||||
{
|
||||
switch( nElement )
|
||||
{
|
||||
case MCE_TOKEN( AlternateContent ):
|
||||
aMceState.push_back( MCE_STARTED );
|
||||
break;
|
||||
|
||||
case MCE_TOKEN( Choice ):
|
||||
{
|
||||
OUString aRequires = rAttribs.getString( ( XML_Requires ), OUString::createFromAscii("none") );
|
||||
aRequires = getFilter().getNamespaceURL( aRequires );
|
||||
if( getFilter().getNamespaceId( aRequires ) > 0 && !aMceState.empty() && aMceState.back() == MCE_STARTED )
|
||||
aMceState.back() = MCE_FOUND_CHOICE;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case MCE_TOKEN( Fallback ):
|
||||
if( !aMceState.empty() && aMceState.back() == MCE_STARTED )
|
||||
break;
|
||||
return false;
|
||||
default:
|
||||
{
|
||||
OUString str = rAttribs.getString( MCE_TOKEN( Ignorable ), OUString() );
|
||||
if( !str.isEmpty() )
|
||||
{
|
||||
Sequence< ::com::sun::star::xml::FastAttribute > attrs = rAttribs.getFastAttributeList()->getFastAttributes();
|
||||
// printf("MCE: %s\n", ::rtl::OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() );
|
||||
// TODO: Check & Get the namespaces in "Ignorable"
|
||||
// printf("NS: %d : %s\n", attrs.getLength(), ::rtl::OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() );
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// com.sun.star.xml.sax.XFastContextHandler interface -------------------------
|
||||
|
||||
Reference< XFastContextHandler > SAL_CALL FragmentHandler2::createFastChildContext(
|
||||
sal_Int32 nElement, const Reference< XFastAttributeList >& rxAttribs ) throw( SAXException, RuntimeException )
|
||||
{
|
||||
if( getNamespace( nElement ) == NMSP_mce ) // TODO for checking 'Ignorable'
|
||||
{
|
||||
if( prepareMceContext( nElement, AttributeList( rxAttribs ) ) )
|
||||
return getFastContextHandler();
|
||||
return NULL;
|
||||
}
|
||||
return implCreateChildContext( nElement, rxAttribs );
|
||||
}
|
||||
|
||||
|
@ -83,6 +134,14 @@ void SAL_CALL FragmentHandler2::characters( const OUString& rChars ) throw( SAXE
|
|||
|
||||
void SAL_CALL FragmentHandler2::endFastElement( sal_Int32 nElement ) throw( SAXException, RuntimeException )
|
||||
{
|
||||
/* If MCE */
|
||||
switch( nElement )
|
||||
{
|
||||
case MCE_TOKEN( AlternateContent ):
|
||||
aMceState.pop_back();
|
||||
break;
|
||||
}
|
||||
|
||||
implEndElement( nElement );
|
||||
}
|
||||
|
||||
|
@ -150,4 +209,4 @@ void FragmentHandler2::finalizeImport()
|
|||
} // namespace core
|
||||
} // namespace oox
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||
|
|
|
@ -141,6 +141,8 @@ XmlFilterBaseImpl::XmlFilterBaseImpl( const Reference< XComponentContext >& rxCo
|
|||
|
||||
maFastParser.registerNamespace( NMSP_ax );
|
||||
maFastParser.registerNamespace( NMSP_xm );
|
||||
maFastParser.registerNamespace( NMSP_mce );
|
||||
maFastParser.registerNamespace( NMSP_mceTest );
|
||||
}
|
||||
|
||||
|
||||
|
@ -272,6 +274,16 @@ bool XmlFilterBase::importFragment( const ::rtl::Reference< FragmentHandler >& r
|
|||
return false;
|
||||
}
|
||||
|
||||
OUString XmlFilterBase::getNamespaceURL( const OUString& rPrefix )
|
||||
{
|
||||
return mxImpl->maFastParser.getNamespaceURL( rPrefix );
|
||||
}
|
||||
|
||||
sal_Int32 XmlFilterBase::getNamespaceId( const OUString& rUrl )
|
||||
{
|
||||
return mxImpl->maFastParser.getNamespaceId( rUrl );
|
||||
}
|
||||
|
||||
RelationsRef XmlFilterBase::importRelations( const OUString& rFragmentPath )
|
||||
{
|
||||
// try to find cached relations
|
||||
|
|
1
oox/source/token/namespaces.hxx.tail
Normal file → Executable file
1
oox/source/token/namespaces.hxx.tail
Normal file → Executable file
|
@ -27,6 +27,7 @@ inline sal_Int32 getNamespace( sal_Int32 nToken ) { return nToken & NMSP_MASK; }
|
|||
#define XLS_TOKEN( token ) (::oox::NMSP_xls | XML_##token)
|
||||
#define XM_TOKEN( token ) (::oox::NMSP_xm | XML_##token)
|
||||
#define XML_TOKEN( token ) (::oox::NMSP_xml | XML_##token)
|
||||
#define MCE_TOKEN( token ) (::oox::NMSP_mce | XML_##token)
|
||||
|
||||
// ============================================================================
|
||||
|
||||
|
|
|
@ -50,3 +50,5 @@ dc http://purl.org/dc/elements/1.1/
|
|||
dcTerms http://purl.org/dc/terms/
|
||||
xm http://schemas.microsoft.com/office/excel/2006/main
|
||||
sprm http://sprm
|
||||
mce http://schemas.openxmlformats.org/markup-compatibility/2006
|
||||
mceTest http://schemas.openxmlformats.org/spreadsheetml/2006/main/v2
|
||||
|
|
|
@ -37,6 +37,7 @@ AbbreviatedCaseNumber
|
|||
Accel
|
||||
Accel2
|
||||
AlbumTitle
|
||||
AlternateContent
|
||||
Always
|
||||
Anchor
|
||||
AppVersion
|
||||
|
@ -79,6 +80,7 @@ Characters
|
|||
CharactersWithSpaces
|
||||
Checkbox
|
||||
Checked
|
||||
Choice
|
||||
City
|
||||
ClientData
|
||||
ColHidden
|
||||
|
@ -142,6 +144,7 @@ EnhancedMetaFile
|
|||
Extend
|
||||
Extension
|
||||
External
|
||||
Fallback
|
||||
False
|
||||
FieldCodes
|
||||
FileBinding
|
||||
|
@ -183,6 +186,7 @@ IDREF
|
|||
IDREFS
|
||||
Icon
|
||||
Id
|
||||
Ignorable
|
||||
Inc
|
||||
Institution
|
||||
Internal
|
||||
|
@ -324,6 +328,7 @@ Relationships
|
|||
RelationshipsGroupReference
|
||||
Report
|
||||
Reporter
|
||||
Requires
|
||||
Right
|
||||
RootElement
|
||||
Row
|
||||
|
|
Loading…
Reference in a new issue