[Libreoffice-commits] core.git: filter/source include/xmloff sc/source xmloff/Library_xof.mk xmloff/source

Mohammed Abdul Azeem azeemmysore at gmail.com
Wed Jan 25 11:21:17 UTC 2017


 filter/source/odfflatxml/OdfFlatXml.cxx                |    8 
 filter/source/xsltfilter/XSLTFilter.cxx                |    8 
 include/xmloff/xmlimp.hxx                              |    1 
 include/xmloff/xmlmetai.hxx                            |    3 
 include/xmloff/xmltoken.hxx                            |    4 
 sc/source/filter/xml/XMLEmptyContext.cxx               |   18 -
 sc/source/filter/xml/XMLEmptyContext.hxx               |   12 
 sc/source/filter/xml/importcontext.cxx                 |   20 +
 sc/source/filter/xml/importcontext.hxx                 |   12 
 sc/source/filter/xml/xmlbodyi.cxx                      |  108 +++++--
 sc/source/filter/xml/xmlbodyi.hxx                      |   19 +
 sc/source/filter/xml/xmlcelli.cxx                      |  231 ++++++++---------
 sc/source/filter/xml/xmlcelli.hxx                      |    8 
 sc/source/filter/xml/xmlimprt.cxx                      |  197 ++++++++++++--
 sc/source/filter/xml/xmlimprt.hxx                      |    9 
 sc/source/filter/xml/xmlrowi.cxx                       |  146 +++++-----
 sc/source/filter/xml/xmlrowi.hxx                       |   31 +-
 sc/source/filter/xml/xmltabi.cxx                       |  145 ++++++----
 sc/source/filter/xml/xmltabi.hxx                       |   13 
 sc/source/filter/xml/xmlwrap.cxx                       |    8 
 xmloff/Library_xof.mk                                  |    4 
 xmloff/source/core/xmlictxt.cxx                        |    6 
 xmloff/source/core/xmltoken.cxx                        |    4 
 xmloff/source/meta/xmlmetai.cxx                        |   13 
 xmloff/source/token/tokens.txt                         |    4 
 xmloff/source/transform/ChartPlotAreaOASISTContext.cxx |    4 
 xmloff/source/transform/ControlOASISTContext.cxx       |    4 
 xmloff/source/transform/ControlOOoTContext.cxx         |    4 
 xmloff/source/transform/EventOOoTContext.cxx           |    5 
 xmloff/source/transform/FormPropOASISTContext.cxx      |    4 
 xmloff/source/transform/FormPropOOoTContext.cxx        |    5 
 xmloff/source/transform/FrameOASISTContext.cxx         |    5 
 xmloff/source/transform/FrameOOoTContext.cxx           |    4 
 xmloff/source/transform/MetaTContext.cxx               |    6 
 xmloff/source/transform/NotesTContext.cxx              |    4 
 xmloff/source/transform/OOo2Oasis.cxx                  |   12 
 xmloff/source/transform/Oasis2OOo.cxx                  |    4 
 xmloff/source/transform/PersAttrListTContext.cxx       |    4 
 xmloff/source/transform/ProcAddAttrTContext.cxx        |    2 
 xmloff/source/transform/ProcAttrTContext.cxx           |    4 
 xmloff/source/transform/RenameElemTContext.cxx         |    4 
 xmloff/source/transform/StyleOASISTContext.cxx         |   10 
 xmloff/source/transform/StyleOOoTContext.cxx           |    9 
 xmloff/source/transform/TransformerBase.cxx            |   57 ++++
 xmloff/source/transform/TransformerBase.hxx            |   15 +
 xmloff/source/transform/TransformerContext.cxx         |    4 
 46 files changed, 789 insertions(+), 413 deletions(-)

New commits:
commit 8154953add163554c00935486a1cf5677cef2609
Author: Mohammed Abdul Azeem <azeemmysore at gmail.com>
Date:   Mon Sep 5 14:38:30 2016 +0530

    ScXMLTableRowCellContext implements fast interfaces:
    
    Implementation of fast interfaces for contexts in path from
    ScXMLImport::CreateFastContext to ScXMLTableRowCellContext.
    FastParser is enabled and duplicates are avoided at all
    possible places.
    OOoXML filters still need those legacy paths we removed,
    so I had to temporarily map them to fast elements, which
    would increase their load time, but hopefully it should
    help us in the long run.
    
    Change-Id: Ie997a9a8b72787da2356abc99ea2cd57c2e5b670
    Reviewed-on: https://gerrit.libreoffice.org/28648
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Michael Meeks <michael.meeks at collabora.com>
    Tested-by: Michael Meeks <michael.meeks at collabora.com>

diff --git a/filter/source/odfflatxml/OdfFlatXml.cxx b/filter/source/odfflatxml/OdfFlatXml.cxx
index f8744ee..f39fc00 100644
--- a/filter/source/odfflatxml/OdfFlatXml.cxx
+++ b/filter/source/odfflatxml/OdfFlatXml.cxx
@@ -29,6 +29,7 @@
 #include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
 #include <com/sun/star/xml/sax/SAXException.hpp>
 #include <com/sun/star/xml/sax/Writer.hpp>
+#include <com/sun/star/xml/sax/XFastParser.hpp>
 
 #include <com/sun/star/io/XInputStream.hpp>
 #include <com/sun/star/io/XOutputStream.hpp>
@@ -142,6 +143,8 @@ OdfFlatXml::importer(
     inputSource.sSystemId = url;
     inputSource.sPublicId = url;
     inputSource.aInputStream = inputStream;
+    css::uno::Reference< css::xml::sax::XFastParser > xFastParser = dynamic_cast<
+                            css::xml::sax::XFastParser* >( docHandler.get() );
     saxParser->setDocumentHandler(docHandler);
     try
     {
@@ -149,7 +152,10 @@ OdfFlatXml::importer(
         if ( xSeekable.is() )
             xSeekable->seek( 0 );
 
-        saxParser->parseStream(inputSource);
+        if( xFastParser.is() )
+            xFastParser->parseStream( inputSource );
+        else
+            saxParser->parseStream(inputSource);
     }
     catch (const Exception &exc)
     {
diff --git a/filter/source/xsltfilter/XSLTFilter.cxx b/filter/source/xsltfilter/XSLTFilter.cxx
index 38dbb8a..468757f 100644
--- a/filter/source/xsltfilter/XSLTFilter.cxx
+++ b/filter/source/xsltfilter/XSLTFilter.cxx
@@ -42,6 +42,7 @@
 #include <com/sun/star/xml/sax/InputSource.hpp>
 #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
 #include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
+#include <com/sun/star/xml/sax/XFastParser.hpp>
 #include <com/sun/star/xml/sax/SAXException.hpp>
 #include <com/sun/star/xml/sax/Writer.hpp>
 #include <com/sun/star/xml/XImportFilter.hpp>
@@ -357,6 +358,8 @@ namespace XSLT
 
                         // set doc handler
                         xSaxParser->setDocumentHandler(xHandler);
+                        css::uno::Reference< css::xml::sax::XFastParser > xFastParser = dynamic_cast<
+                            css::xml::sax::XFastParser* >( xHandler.get() );
 
                         // transform
                         m_tcontrol->start();
@@ -388,7 +391,10 @@ namespace XSLT
                                 result = m_cTransformed.wait(&timeout);
                         };
                         if (!m_bError) {
-                                xSaxParser->parseStream(aInput);
+                                if( xFastParser.is() )
+                                    xFastParser->parseStream( aInput );
+                                else
+                                    xSaxParser->parseStream( aInput );
                         }
                         m_tcontrol->terminate();
                         return !m_bError;
diff --git a/include/xmloff/xmlimp.hxx b/include/xmloff/xmlimp.hxx
index e4b7cd5..0208b3da 100644
--- a/include/xmloff/xmlimp.hxx
+++ b/include/xmloff/xmlimp.hxx
@@ -570,6 +570,7 @@ public:
     virtual void NotifyEmbeddedFontRead() {};
 
     bool needFixPositionAfterZ() const;
+    const css::uno::Reference< css::xml::sax::XFastNamespaceHandler > getNamespaceHandler() { return maNamespaceHandler.get(); }
 };
 
 inline rtl::Reference< XMLTextImportHelper > const & SvXMLImport::GetTextImport()
diff --git a/include/xmloff/xmlmetai.hxx b/include/xmloff/xmlmetai.hxx
index 1ae3cec..3aab9d1 100644
--- a/include/xmloff/xmlmetai.hxx
+++ b/include/xmloff/xmlmetai.hxx
@@ -44,6 +44,9 @@ public:
         const OUString& rLName,
         const css::uno::Reference< css::document::XDocumentProperties>& xDocProps);
 
+    SvXMLMetaDocumentContext(SvXMLImport& rImport, sal_Int32 nElement,
+        const css::uno::Reference< css::document::XDocumentProperties>& xDocProps);
+
     virtual ~SvXMLMetaDocumentContext() override;
 
     virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
diff --git a/include/xmloff/xmltoken.hxx b/include/xmloff/xmltoken.hxx
index 1698737..989fa33 100644
--- a/include/xmloff/xmltoken.hxx
+++ b/include/xmloff/xmltoken.hxx
@@ -575,6 +575,8 @@ namespace xmloff { namespace token {
         XML_DATE_ADJUST,
         XML_DATE_STYLE,
         XML_DATE_TIME,
+        XML_DATE_TIME_UPDATE,
+        XML_DATE_TIME_VISIBLE,
         XML_DATE_VALUE,
         XML_DATETIME,
         XML_DAY,
@@ -846,6 +848,7 @@ namespace xmloff { namespace token {
         XML_FOOTER_FIRST,
         XML_FOOTER_LEFT,
         XML_FOOTER_STYLE,
+        XML_FOOTER_VISIBLE,
         XML_FOOTNOTE,
         XML_FOOTNOTE_BODY,
         XML_FOOTNOTE_CITATION,
@@ -1378,6 +1381,7 @@ namespace xmloff { namespace token {
         XML_PAGE_MASTER_NAME,
         XML_PAGE_NAME,
         XML_PAGE_NUMBER,
+        XML_PAGE_NUMBER_VISIBLE,
         XML_PAGE_START_MARGIN,
         XML_PAGE_STYLE_NAME,
         XML_PAGE_THUMBNAIL,
diff --git a/sc/source/filter/xml/XMLEmptyContext.cxx b/sc/source/filter/xml/XMLEmptyContext.cxx
index 8e7abc8..f108b43 100644
--- a/sc/source/filter/xml/XMLEmptyContext.cxx
+++ b/sc/source/filter/xml/XMLEmptyContext.cxx
@@ -21,9 +21,8 @@
 #include "xmlimprt.hxx"
 
 ScXMLEmptyContext::ScXMLEmptyContext( ScXMLImport& rImport,
-                                      sal_uInt16 nPrfx,
-                                      const OUString& rLName) :
-    ScXMLImportContext( rImport, nPrfx, rLName )
+                                      sal_Int32 /*nElement*/ ) :
+    ScXMLImportContext( rImport )
 {
 }
 
@@ -31,17 +30,14 @@ ScXMLEmptyContext::~ScXMLEmptyContext()
 {
 }
 
-SvXMLImportContext *ScXMLEmptyContext::CreateChildContext( sal_uInt16 nPrefix,
-                                            const OUString& rLName,
-                                            const css::uno::Reference<css::xml::sax::XAttributeList>& /* xAttrList */ )
+css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL
+    ScXMLEmptyContext::createFastChildContext( sal_Int32 nElement,
+    const css::uno::Reference< css::xml::sax::XFastAttributeList > & /*xAttrList*/ )
+    throw (css::uno::RuntimeException, css::xml::sax::SAXException, std::exception)
 {
-    SvXMLImportContext *pContext = new ScXMLEmptyContext(GetScImport(), nPrefix, rLName);
+    SvXMLImportContext *pContext = new ScXMLEmptyContext( GetScImport(), nElement );
 
     return pContext;
 }
 
-void ScXMLEmptyContext::EndElement()
-{
-}
-
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLEmptyContext.hxx b/sc/source/filter/xml/XMLEmptyContext.hxx
index 2587885..e003cde 100644
--- a/sc/source/filter/xml/XMLEmptyContext.hxx
+++ b/sc/source/filter/xml/XMLEmptyContext.hxx
@@ -27,16 +27,14 @@
 class ScXMLEmptyContext : public ScXMLImportContext
 {
 public:
-    ScXMLEmptyContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
-                        const OUString& rLName);
+    ScXMLEmptyContext( ScXMLImport& rImport, sal_Int32 nElement );
 
     virtual ~ScXMLEmptyContext() override;
 
-    virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
-                                     const OUString& rLocalName,
-                                     const css::uno::Reference<css::xml::sax::XAttributeList>& xAttrList ) override;
-
-    virtual void EndElement() override;
+    virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL
+        createFastChildContext( sal_Int32 nElement,
+        const css::uno::Reference<css::xml::sax::XFastAttributeList>& xAttrList )
+        throw (css::uno::RuntimeException, css::xml::sax::SAXException, std::exception ) override;
 };
 
 #endif
diff --git a/sc/source/filter/xml/importcontext.cxx b/sc/source/filter/xml/importcontext.cxx
index 9e851c6..56196ea 100644
--- a/sc/source/filter/xml/importcontext.cxx
+++ b/sc/source/filter/xml/importcontext.cxx
@@ -15,6 +15,11 @@ ScXMLImportContext::ScXMLImportContext(ScXMLImport& rImport, sal_uInt16 nPrefix,
 {
 }
 
+ScXMLImportContext::ScXMLImportContext(SvXMLImport& rImport ) :
+    SvXMLImportContext( rImport )
+{
+}
+
 ScXMLImport& ScXMLImportContext::GetScImport()
 {
     return static_cast<ScXMLImport&>(GetImport());
@@ -25,4 +30,19 @@ const ScXMLImport& ScXMLImportContext::GetScImport() const
     return static_cast<const ScXMLImport&>(GetImport());
 }
 
+void SAL_CALL ScXMLImportContext::startFastElement(sal_Int32 /*nElement*/, const css::uno::Reference< css::xml::sax::XFastAttributeList > & /*xAttrList*/)
+    throw (css::uno::RuntimeException, css::xml::sax::SAXException, std::exception)
+{
+}
+
+void SAL_CALL ScXMLImportContext::endFastElement(sal_Int32 /*nElement*/)
+    throw (css::uno::RuntimeException, css::xml::sax::SAXException, std::exception)
+{
+}
+
+void SAL_CALL ScXMLImportContext::characters(const OUString &)
+    throw (css::uno::RuntimeException, css::xml::sax::SAXException, std::exception)
+{
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/importcontext.hxx b/sc/source/filter/xml/importcontext.hxx
index 6b660631..0d9a136 100644
--- a/sc/source/filter/xml/importcontext.hxx
+++ b/sc/source/filter/xml/importcontext.hxx
@@ -24,6 +24,18 @@ public:
     ScXMLImportContext(
         ScXMLImport& rImport, sal_uInt16 nPrefix, const OUString& rLocalName);
 
+    ScXMLImportContext( SvXMLImport& rImport );
+
+    virtual void SAL_CALL startFastElement (sal_Int32 nElement,
+        const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
+        throw (css::uno::RuntimeException, css::xml::sax::SAXException, std::exception) override;
+
+    virtual void SAL_CALL characters(const OUString & aChars)
+            throw (css::uno::RuntimeException, css::xml::sax::SAXException, std::exception) override;
+
+    virtual void SAL_CALL endFastElement(sal_Int32 nElement)
+            throw (css::uno::RuntimeException, css::xml::sax::SAXException, std::exception) override;
+
 protected:
     ScXMLImport& GetScImport();
     const ScXMLImport& GetScImport() const;
diff --git a/sc/source/filter/xml/xmlbodyi.cxx b/sc/source/filter/xml/xmlbodyi.cxx
index 17cc879..f31079d 100644
--- a/sc/source/filter/xml/xmlbodyi.cxx
+++ b/sc/source/filter/xml/xmlbodyi.cxx
@@ -41,6 +41,7 @@
 #include "scerrors.hxx"
 #include "tabprotection.hxx"
 #include "datastreamimport.hxx"
+#include <sax/fastattribs.hxx>
 
 #include <xmloff/xmltkmap.hxx>
 #include <xmloff/xmltoken.hxx>
@@ -56,10 +57,9 @@ using namespace com::sun::star;
 using namespace xmloff::token;
 
 ScXMLBodyContext::ScXMLBodyContext( ScXMLImport& rImport,
-                                              sal_uInt16 nPrfx,
-                                                   const OUString& rLName,
-                                              const uno::Reference<xml::sax::XAttributeList>& xAttrList ) :
-    ScXMLImportContext( rImport, nPrfx, rLName ),
+                                    sal_Int32 /*nElement*/,
+                                    const uno::Reference<xml::sax::XFastAttributeList>& xAttrList ) :
+    ScXMLImportContext( rImport ),
     sPassword(),
     meHash1(PASSHASH_SHA1),
     meHash2(PASSHASH_UNSPECIFIED),
@@ -90,30 +90,35 @@ ScXMLBodyContext::ScXMLBodyContext( ScXMLImport& rImport,
         pDoc->SetStorageGrammar( eGrammar);
     }
 
-    sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
-    for( sal_Int16 i=0; i < nAttrCount; ++i )
-    {
-        const OUString& sAttrName(xAttrList->getNameByIndex( i ));
-        OUString aLocalName;
-        sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
-                                            sAttrName, &aLocalName );
-        const OUString& sValue(xAttrList->getValueByIndex( i ));
+    if( !xAttrList.is() )
+        return;
+
+    sax_fastparser::FastAttributeList *pAttribList;
+    assert( dynamic_cast< sax_fastparser::FastAttributeList *>( xAttrList.get() ) != nullptr );
+    pAttribList = static_cast< sax_fastparser::FastAttributeList *>( xAttrList.get() );
 
-        if (nPrefix == XML_NAMESPACE_TABLE)
+    const std::vector< sal_Int32 >& rAttrList = pAttribList->getFastAttributeTokens();
+    for ( size_t i = 0; i < rAttrList.size(); i++ )
+    {
+        sal_Int32 nToken = rAttrList[ i ];
+        const OUString sValue = OUString(pAttribList->getFastAttributeValue(i),
+                                    pAttribList->AttributeValueLength(i), RTL_TEXTENCODING_UTF8);
+        if( NAMESPACE_TOKEN( XML_NAMESPACE_TABLE ) == ( nToken & NMSP_MASK ) )
         {
-            if (IsXMLToken(aLocalName, XML_STRUCTURE_PROTECTED))
+            const sal_Int32 nLocalToken = nToken & TOKEN_MASK;
+            if( nLocalToken == XML_STRUCTURE_PROTECTED )
                 bProtected = IsXMLToken(sValue, XML_TRUE);
-            else if (IsXMLToken(aLocalName, XML_PROTECTION_KEY))
+            else if ( nLocalToken == XML_PROTECTION_KEY )
                 sPassword = sValue;
-            else if (IsXMLToken(aLocalName, XML_PROTECTION_KEY_DIGEST_ALGORITHM))
-                meHash1 = ScPassHashHelper::getHashTypeFromURI(sValue);
-            else if (IsXMLToken(aLocalName, XML_PROTECTION_KEY_DIGEST_ALGORITHM_2))
-                meHash2 = ScPassHashHelper::getHashTypeFromURI(sValue);
+            else if (  nLocalToken == XML_PROTECTION_KEY_DIGEST_ALGORITHM )
+                meHash1 = ScPassHashHelper::getHashTypeFromURI( sValue );
+            else if (  nLocalToken == XML_PROTECTION_KEY_DIGEST_ALGORITHM_2 )
+                meHash2 = ScPassHashHelper::getHashTypeFromURI( sValue );
         }
-        else if(nPrefix == XML_NAMESPACE_LO_EXT)
+        else if ( nToken == ( NAMESPACE_TOKEN( XML_NAMESPACE_LO_EXT ) |
+                                        XML_PROTECTION_KEY_DIGEST_ALGORITHM_2 ) )
         {
-            if (IsXMLToken(aLocalName, XML_PROTECTION_KEY_DIGEST_ALGORITHM_2))
-                meHash2 = ScPassHashHelper::getHashTypeFromURI(sValue);
+            meHash2 = ScPassHashHelper::getHashTypeFromURI( sValue );
         }
     }
 }
@@ -154,18 +159,6 @@ SvXMLImportContext *ScXMLBodyContext::CreateChildContext( sal_uInt16 nPrefix,
     case XML_TOK_BODY_LABEL_RANGES:
         pContext = new ScXMLLabelRangesContext( GetScImport(), nPrefix, rLocalName, xAttrList );
         break;
-    case XML_TOK_BODY_TABLE:
-        if (GetScImport().GetTables().GetCurrentSheet() >= MAXTAB)
-        {
-            GetScImport().SetRangeOverflowType(SCWARN_IMPORT_SHEET_OVERFLOW);
-            pContext = new ScXMLEmptyContext(GetScImport(), nPrefix, rLocalName);
-        }
-        else
-        {
-            pContext = new ScXMLTableContext( GetScImport(),nPrefix, rLocalName,
-                                              xAttrList );
-        }
-        break;
     case XML_TOK_BODY_NAMED_EXPRESSIONS:
         pContext = new ScXMLNamedExpressionsContext (
             GetScImport(), nPrefix, rLocalName, xAttrList,
@@ -202,7 +195,49 @@ SvXMLImportContext *ScXMLBodyContext::CreateChildContext( sal_uInt16 nPrefix,
     return pContext;
 }
 
-void ScXMLBodyContext::Characters( const OUString& )
+uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
+        ScXMLBodyContext::createFastChildContext( sal_Int32 nElement,
+        const uno::Reference< xml::sax::XFastAttributeList > & xAttrList )
+        throw (uno::RuntimeException, xml::sax::SAXException, std::exception)
+{
+    ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetScImport().GetModel())->GetSheetSaveData();
+    if ( pSheetData && pSheetData->HasStartPos() )
+    {
+        // stream part to copy ends before the next child element
+        sal_Int32 nEndOffset = GetScImport().GetByteOffset();
+        pSheetData->EndStreamPos( nEndOffset );
+    }
+
+    SvXMLImportContext *pContext = nullptr;
+
+    const SvXMLTokenMap& rTokenMap = GetScImport().GetBodyElemTokenMap();
+    switch( rTokenMap.Get( nElement ) )
+    {
+    case XML_TOK_BODY_TABLE:
+        if (GetScImport().GetTables().GetCurrentSheet() >= MAXTAB)
+        {
+            GetScImport().SetRangeOverflowType(SCWARN_IMPORT_SHEET_OVERFLOW);
+            pContext = new ScXMLEmptyContext(GetScImport(), nElement );
+        }
+        else
+        {
+            pContext = new ScXMLTableContext( GetScImport(),nElement, xAttrList );
+        }
+        break;
+
+    // TODO: handle all other cases
+    default:
+        pContext = new SvXMLImportContext( GetImport() );
+    }
+
+    if( !pContext )
+        pContext = new SvXMLImportContext( GetImport() );
+
+    return pContext;
+}
+
+void SAL_CALL ScXMLBodyContext::characters(const OUString &)
+    throw (uno::RuntimeException, xml::sax::SAXException, std::exception)
 {
     ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetScImport().GetModel())->GetSheetSaveData();
     if ( pSheetData && pSheetData->HasStartPos() )
@@ -214,7 +249,8 @@ void ScXMLBodyContext::Characters( const OUString& )
     // otherwise ignore
 }
 
-void ScXMLBodyContext::EndElement()
+void SAL_CALL ScXMLBodyContext::endFastElement(sal_Int32 /*nElement*/)
+    throw (uno::RuntimeException, xml::sax::SAXException, std::exception)
 {
     ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetScImport().GetModel())->GetSheetSaveData();
     if ( pSheetData && pSheetData->HasStartPos() )
diff --git a/sc/source/filter/xml/xmlbodyi.hxx b/sc/source/filter/xml/xmlbodyi.hxx
index ac9274b..b5176cc 100644
--- a/sc/source/filter/xml/xmlbodyi.hxx
+++ b/sc/source/filter/xml/xmlbodyi.hxx
@@ -40,15 +40,26 @@ class ScXMLBodyContext : public ScXMLImportContext
     ScXMLChangeTrackingImportHelper*    pChangeTrackingImportHelper;
 
 public:
-    ScXMLBodyContext( ScXMLImport& rImport, sal_uInt16 nPrfx, const OUString& rLName,
-                        const css::uno::Reference<css::xml::sax::XAttributeList>& xAttrList );
+
+    ScXMLBodyContext( ScXMLImport& rImport, sal_Int32 nElement,
+                        const css::uno::Reference<css::xml::sax::XFastAttributeList>& xAttrList );
+
     virtual ~ScXMLBodyContext() override;
 
     virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
                                                     const OUString& rLocalName,
                                                     const css::uno::Reference< css::xml::sax::XAttributeList>& xAttrList ) override;
-    virtual void EndElement() override;
-    virtual void Characters( const OUString& rChars ) override;
+
+    virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL
+        createFastChildContext( sal_Int32 nElement,
+        const css::uno::Reference<css::xml::sax::XFastAttributeList>& xAttrList )
+        throw (css::uno::RuntimeException, css::xml::sax::SAXException, std::exception ) override;
+
+    virtual void SAL_CALL endFastElement(sal_Int32 nElement)
+        throw (css::uno::RuntimeException, css::xml::sax::SAXException, std::exception) override;
+
+    virtual void SAL_CALL characters(const OUString & aChars)
+        throw (css::uno::RuntimeException, css::xml::sax::SAXException, std::exception) override;
 };
 
 #endif
diff --git a/sc/source/filter/xml/xmlcelli.cxx b/sc/source/filter/xml/xmlcelli.cxx
index fb8783c..3559cc8 100644
--- a/sc/source/filter/xml/xmlcelli.cxx
+++ b/sc/source/filter/xml/xmlcelli.cxx
@@ -90,6 +90,7 @@
 #include <svl/sharedstringpool.hxx>
 #include <svtools/miscopt.hxx>
 #include <sax/tools/converter.hxx>
+#include <sax/fastattribs.hxx>
 
 #include <com/sun/star/util/NumberFormat.hpp>
 #include <com/sun/star/util/Date.hpp>
@@ -116,12 +117,11 @@ ScXMLTableRowCellContext::Field::~Field()
 }
 
 ScXMLTableRowCellContext::ScXMLTableRowCellContext( ScXMLImport& rImport,
-                                      sal_uInt16 nPrfx,
-                                      const OUString& rLName,
-                                      const css::uno::Reference<css::xml::sax::XAttributeList>& xAttrList,
+                                      sal_Int32 /*nElement*/,
+                                      const css::uno::Reference<css::xml::sax::XFastAttributeList>& xAttrList,
                                       const bool bTempIsCovered,
                                       const sal_Int32 nTempRepeatedRows ) :
-    ScXMLImportContext(rImport, nPrfx, rLName),
+    ScXMLImportContext( rImport ),
     mpEditEngine(GetScImport().GetEditEngine()),
     mnCurParagraph(0),
     pDetectiveObjVec(nullptr),
@@ -155,136 +155,142 @@ ScXMLTableRowCellContext::ScXMLTableRowCellContext( ScXMLImport& rImport,
 
     rXMLImport.SetRemoveLastChar(false);
     rXMLImport.GetTables().AddColumn(bTempIsCovered);
-    const sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
-    OUString aLocalName;
+
     std::unique_ptr<OUString> xStyleName;
     std::unique_ptr<OUString> xCurrencySymbol;
     const SvXMLTokenMap& rTokenMap = rImport.GetTableRowCellAttrTokenMap();
-    for (sal_Int16 i = 0; i < nAttrCount; ++i)
+    if( xAttrList.is() )
     {
-        sal_uInt16 nAttrPrefix = rImport.GetNamespaceMap().GetKeyByAttrName(
-            xAttrList->getNameByIndex(i), &aLocalName);
+        sax_fastparser::FastAttributeList *pAttribList;
+        assert( dynamic_cast< sax_fastparser::FastAttributeList *>( xAttrList.get() ) != nullptr );
+        pAttribList = static_cast< sax_fastparser::FastAttributeList *>( xAttrList.get() );
 
-        const OUString& sValue = xAttrList->getValueByIndex(i);
-        sal_uInt16 nToken = rTokenMap.Get(nAttrPrefix, aLocalName);
-        switch (nToken)
+        const std::vector< sal_Int32 >& rAttrList = pAttribList->getFastAttributeTokens();
+        for ( size_t i = 0; i < rAttrList.size(); i++ )
         {
-            case XML_TOK_TABLE_ROW_CELL_ATTR_STYLE_NAME:
-                xStyleName.reset(new OUString(sValue));
-                mbHasStyle = true;
-            break;
-            case XML_TOK_TABLE_ROW_CELL_ATTR_CONTENT_VALIDATION_NAME:
-                OSL_ENSURE(!maContentValidationName, "here should be only one Validation Name");
-                if (!sValue.isEmpty())
-                    maContentValidationName.reset(sValue);
-            break;
-            case XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_ROWS:
-                bIsMerged = true;
-                nMergedRows = static_cast<SCROW>(sValue.toInt32());
-            break;
-            case XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_COLS:
-                bIsMerged = true;
-                nMergedCols = static_cast<SCCOL>(sValue.toInt32());
-            break;
-            case XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_MATRIX_COLS:
-                bIsMatrix = true;
-                nMatrixCols = static_cast<SCCOL>(sValue.toInt32());
-            break;
-            case XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_MATRIX_ROWS:
-                bIsMatrix = true;
-                nMatrixRows = static_cast<SCROW>(sValue.toInt32());
-            break;
-            case XML_TOK_TABLE_ROW_CELL_ATTR_REPEATED:
-                nColsRepeated = static_cast<SCCOL>(std::min<sal_Int32>( MAXCOLCOUNT,
-                            std::max( sValue.toInt32(), static_cast<sal_Int32>(1) ) ));
-            break;
-            case XML_TOK_TABLE_ROW_CELL_ATTR_VALUE_TYPE:
-                nCellType = GetScImport().GetCellType(sValue);
-                bIsEmpty = false;
-            break;
-            case XML_TOK_TABLE_ROW_CELL_ATTR_NEW_VALUE_TYPE:
-                if(sValue == "error")
-                    mbErrorValue = true;
-                else
-                    nCellType = GetScImport().GetCellType(sValue);
-                bIsEmpty = false;
-                mbNewValueType = true;
-            break;
-            case XML_TOK_TABLE_ROW_CELL_ATTR_VALUE:
+            sal_uInt16 nToken = rTokenMap.Get( rAttrList[ i ] );
+            const OUString sValue = OUString(pAttribList->getFastAttributeValue(i),
+                                    pAttribList->AttributeValueLength(i), RTL_TEXTENCODING_UTF8);
+            switch ( nToken )
             {
-                if (!sValue.isEmpty())
-                {
-                    ::sax::Converter::convertDouble(fValue, sValue);
+                case XML_TOK_TABLE_ROW_CELL_ATTR_STYLE_NAME:
+                    xStyleName.reset(new OUString(sValue));
+                    mbHasStyle = true;
+                break;
+                case XML_TOK_TABLE_ROW_CELL_ATTR_CONTENT_VALIDATION_NAME:
+                    OSL_ENSURE(!maContentValidationName, "here should be only one Validation Name");
+                    if (!sValue.isEmpty())
+                        maContentValidationName.reset(sValue);
+                break;
+                case XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_ROWS:
+                    bIsMerged = true;
+                    nMergedRows = static_cast<SCROW>(sValue.toInt32());
+                break;
+                case XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_COLS:
+                    bIsMerged = true;
+                    nMergedCols = static_cast<SCCOL>(sValue.toInt32());
+                break;
+                case XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_MATRIX_COLS:
+                    bIsMatrix = true;
+                    nMatrixCols = static_cast<SCCOL>(sValue.toInt32());
+                break;
+                case XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_MATRIX_ROWS:
+                    bIsMatrix = true;
+                    nMatrixRows = static_cast<SCROW>(sValue.toInt32());
+                break;
+                case XML_TOK_TABLE_ROW_CELL_ATTR_REPEATED:
+                    nColsRepeated = static_cast<SCCOL>(std::min<sal_Int32>( MAXCOLCOUNT,
+                                std::max( sValue.toInt32(), static_cast<sal_Int32>(1) ) ));
+                break;
+                case XML_TOK_TABLE_ROW_CELL_ATTR_VALUE_TYPE:
+                    nCellType = GetScImport().GetCellType(sValue);
+                    bIsEmpty = false;
+                break;
+                case XML_TOK_TABLE_ROW_CELL_ATTR_NEW_VALUE_TYPE:
+                    if(sValue == "error")
+                        mbErrorValue = true;
+                    else
+                        nCellType = GetScImport().GetCellType(sValue);
                     bIsEmpty = false;
+                    mbNewValueType = true;
+                break;
+                case XML_TOK_TABLE_ROW_CELL_ATTR_VALUE:
+                {
+                    if (!sValue.isEmpty())
+                    {
+                        ::sax::Converter::convertDouble(fValue, sValue);
+                        bIsEmpty = false;
 
-                    //if office:value="0", let's get the text:p in case this is
-                    //a special case in HasSpecialCaseFormulaText(). If it
-                    //turns out not to be a special case, we'll use the 0 value.
-                    if(fValue == 0.0)
-                        bFormulaTextResult = true;
+                        //if office:value="0", let's get the text:p in case this is
+                        //a special case in HasSpecialCaseFormulaText(). If it
+                        //turns out not to be a special case, we'll use the 0 value.
+                        if(fValue == 0.0)
+                            bFormulaTextResult = true;
+                    }
                 }
-            }
-            break;
-            case XML_TOK_TABLE_ROW_CELL_ATTR_DATE_VALUE:
-            {
-                if (!sValue.isEmpty() && rXMLImport.SetNullDateOnUnitConverter())
+                break;
+                case XML_TOK_TABLE_ROW_CELL_ATTR_DATE_VALUE:
                 {
-                    rXMLImport.GetMM100UnitConverter().convertDateTime(fValue, sValue);
-                    bIsEmpty = false;
+                    if (!sValue.isEmpty() && rXMLImport.SetNullDateOnUnitConverter())
+                    {
+                        rXMLImport.GetMM100UnitConverter().convertDateTime(fValue, sValue);
+                        bIsEmpty = false;
+                    }
                 }
-            }
-            break;
-            case XML_TOK_TABLE_ROW_CELL_ATTR_TIME_VALUE:
-            {
-                if (!sValue.isEmpty())
+                break;
+                case XML_TOK_TABLE_ROW_CELL_ATTR_TIME_VALUE:
                 {
-                    ::sax::Converter::convertDuration(fValue, sValue);
-                    bIsEmpty = false;
+                    if (!sValue.isEmpty())
+                    {
+                        ::sax::Converter::convertDuration(fValue, sValue);
+                        bIsEmpty = false;
+                    }
                 }
-            }
-            break;
-            case XML_TOK_TABLE_ROW_CELL_ATTR_STRING_VALUE:
-            {
-                if (!sValue.isEmpty())
+                break;
+                case XML_TOK_TABLE_ROW_CELL_ATTR_STRING_VALUE:
                 {
-                    OSL_ENSURE(!maStringValue, "here should be only one string value");
-                    maStringValue.reset(sValue);
-                    bIsEmpty = false;
+                    if (!sValue.isEmpty())
+                    {
+                        OSL_ENSURE(!maStringValue, "here should be only one string value");
+                        maStringValue.reset(sValue);
+                        bIsEmpty = false;
+                    }
                 }
-            }
-            break;
-            case XML_TOK_TABLE_ROW_CELL_ATTR_BOOLEAN_VALUE:
-            {
-                if (!sValue.isEmpty())
+                break;
+                case XML_TOK_TABLE_ROW_CELL_ATTR_BOOLEAN_VALUE:
                 {
-                    if ( IsXMLToken(sValue, XML_TRUE) )
-                        fValue = 1.0;
-                    else if ( IsXMLToken(sValue, XML_FALSE) )
-                        fValue = 0.0;
-                    else
-                        ::sax::Converter::convertDouble(fValue, sValue);
-                    bIsEmpty = false;
+                    if (!sValue.isEmpty())
+                    {
+                        if ( IsXMLToken(sValue, XML_TRUE) )
+                            fValue = 1.0;
+                        else if ( IsXMLToken(sValue, XML_FALSE) )
+                            fValue = 0.0;
+                        else
+                            ::sax::Converter::convertDouble(fValue, sValue);
+                        bIsEmpty = false;
+                    }
                 }
-            }
-            break;
-            case XML_TOK_TABLE_ROW_CELL_ATTR_FORMULA:
-            {
-                if (!sValue.isEmpty())
+                break;
+                case XML_TOK_TABLE_ROW_CELL_ATTR_FORMULA:
                 {
-                    OSL_ENSURE(!maFormula, "here should be only one formula");
-                    OUString aFormula, aFormulaNmsp;
-                    rXMLImport.ExtractFormulaNamespaceGrammar( aFormula, aFormulaNmsp, eGrammar, sValue );
-                    maFormula.reset( FormulaWithNamespace(aFormula, aFormulaNmsp) );
+                    if (!sValue.isEmpty())
+                    {
+                        OSL_ENSURE(!maFormula, "here should be only one formula");
+                        OUString aFormula, aFormulaNmsp;
+                        rXMLImport.ExtractFormulaNamespaceGrammar( aFormula, aFormulaNmsp, eGrammar, sValue );
+                        maFormula.reset( FormulaWithNamespace(aFormula, aFormulaNmsp) );
+                    }
                 }
+                break;
+                case XML_TOK_TABLE_ROW_CELL_ATTR_CURRENCY:
+                    xCurrencySymbol.reset(new OUString(sValue));
+                break;
+                default:
+                    ;
             }
-            break;
-            case XML_TOK_TABLE_ROW_CELL_ATTR_CURRENCY:
-                xCurrencySymbol.reset(new OUString(sValue));
-            break;
-            default:
-                ;
         }
     }
+
     if (maFormula)
     {
         if (nCellType == util::NumberFormat::TEXT)
@@ -1490,7 +1496,8 @@ bool ScXMLTableRowCellContext::IsPossibleErrorString() const
             GetScImport().GetFormulaErrorConstant(*maStringValue) != FormulaError::NONE);
 }
 
-void ScXMLTableRowCellContext::EndElement()
+void SAL_CALL ScXMLTableRowCellContext::endFastElement(sal_Int32 /*nElement*/)
+    throw (uno::RuntimeException, xml::sax::SAXException, std::exception)
 {
     HasSpecialCaseFormulaText();
     if( bFormulaTextResult && (mbPossibleErrorCell || mbCheckWithCompilerForError) )
diff --git a/sc/source/filter/xml/xmlcelli.hxx b/sc/source/filter/xml/xmlcelli.hxx
index 39bb757..845bdc0 100644
--- a/sc/source/filter/xml/xmlcelli.hxx
+++ b/sc/source/filter/xml/xmlcelli.hxx
@@ -129,9 +129,8 @@ class ScXMLTableRowCellContext : public ScXMLImportContext
 
 public:
 
-    ScXMLTableRowCellContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
-                       const OUString& rLName,
-                       const css::uno::Reference<css::xml::sax::XAttributeList>& xAttrList,
+    ScXMLTableRowCellContext( ScXMLImport& rImport, sal_Int32 nElement,
+                       const css::uno::Reference<css::xml::sax::XFastAttributeList>& xAttrList,
                        const bool bIsCovered, const sal_Int32 nRepeatedRows );
 
     virtual ~ScXMLTableRowCellContext() override;
@@ -151,7 +150,8 @@ public:
     void SetDetectiveObj( const ScAddress& rPosition );
     void SetCellRangeSource( const ScAddress& rPosition );
 
-    virtual void EndElement() override;
+    virtual void SAL_CALL endFastElement(sal_Int32 nElement)
+            throw (css::uno::RuntimeException, css::xml::sax::SAXException, std::exception) override;
 };
 
 #endif
diff --git a/sc/source/filter/xml/xmlimprt.cxx b/sc/source/filter/xml/xmlimprt.cxx
index c798e19..bb47480 100644
--- a/sc/source/filter/xml/xmlimprt.cxx
+++ b/sc/source/filter/xml/xmlimprt.cxx
@@ -73,6 +73,7 @@
 #include "editattributemap.hxx"
 #include "documentimport.hxx"
 #include "pivotsource.hxx"
+#include "importcontext.hxx"
 #include <unonames.hxx>
 #include <numformat.hxx>
 
@@ -233,9 +234,28 @@ public:
         const OUString& rLName,
         const uno::Reference<xml::sax::XAttributeList>& xAttrList );
 
+    ScXMLDocContext_Impl( ScXMLImport& rImport,
+        sal_Int32 nElement,
+        const uno::Reference<xml::sax::XFastAttributeList>& xAttrList );
+
     virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
         const OUString& rLocalName,
         const uno::Reference<xml::sax::XAttributeList>& xAttrList ) override;
+
+    virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL
+        createFastChildContext( sal_Int32 nElement,
+        const css::uno::Reference<css::xml::sax::XFastAttributeList>& xAttrList )
+        throw (css::uno::RuntimeException, css::xml::sax::SAXException, std::exception ) override;
+
+    virtual void SAL_CALL startFastElement (sal_Int32 nElement,
+        const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
+        throw (css::uno::RuntimeException, css::xml::sax::SAXException, std::exception) override;
+
+    virtual void SAL_CALL characters(const OUString & aChars)
+        throw (css::uno::RuntimeException, css::xml::sax::SAXException, std::exception) override;
+
+    virtual void SAL_CALL endFastElement(sal_Int32 nElement)
+        throw (css::uno::RuntimeException, css::xml::sax::SAXException, std::exception) override;
 };
 
 ScXMLDocContext_Impl::ScXMLDocContext_Impl( ScXMLImport& rImport, sal_uInt16 nPrfx,
@@ -246,6 +266,12 @@ SvXMLImportContext( rImport, nPrfx, rLName )
 
 }
 
+ScXMLDocContext_Impl::ScXMLDocContext_Impl( ScXMLImport& rImport, sal_Int32 /*nElement*/,
+                                           const uno::Reference<xml::sax::XFastAttributeList>& /*xAttrList*/ ) :
+SvXMLImportContext( rImport )
+{
+}
+
 // context for flat file xml format
 class ScXMLFlatDocContext_Impl
     : public ScXMLDocContext_Impl, public SvXMLMetaDocumentContext
@@ -256,9 +282,26 @@ public:
         const uno::Reference<xml::sax::XAttributeList>& i_xAttrList,
         const uno::Reference<document::XDocumentProperties>& i_xDocProps);
 
+    ScXMLFlatDocContext_Impl( ScXMLImport& i_rImport,
+        sal_Int32 nElement,
+        const uno::Reference<xml::sax::XFastAttributeList>& i_xAttrList,
+        const uno::Reference<document::XDocumentProperties>& i_xDocProps);
+
     virtual SvXMLImportContext *CreateChildContext(
         sal_uInt16 i_nPrefix, const OUString& i_rLocalName,
         const uno::Reference<xml::sax::XAttributeList>& i_xAttrList) override;
+
+    virtual void SAL_CALL startFastElement (sal_Int32 nElement,
+        const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList)
+        throw (css::uno::RuntimeException, css::xml::sax::SAXException, std::exception) override;
+
+    virtual void SAL_CALL endFastElement(sal_Int32 nElement)
+            throw (css::uno::RuntimeException, css::xml::sax::SAXException, std::exception) override;
+
+    virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL
+        createFastChildContext( sal_Int32 nElement,
+        const css::uno::Reference<css::xml::sax::XFastAttributeList>& xAttrList )
+        throw (css::uno::RuntimeException, css::xml::sax::SAXException, std::exception ) override;
 };
 
 ScXMLFlatDocContext_Impl::ScXMLFlatDocContext_Impl( ScXMLImport& i_rImport,
@@ -272,6 +315,15 @@ SvXMLMetaDocumentContext(i_rImport, i_nPrefix, i_rLName,
 {
 }
 
+ScXMLFlatDocContext_Impl::ScXMLFlatDocContext_Impl( ScXMLImport& i_rImport, sal_Int32 nElement,
+                                                   const uno::Reference<xml::sax::XFastAttributeList>& i_xAttrList,
+                                                   const uno::Reference<document::XDocumentProperties>& i_xDocProps) :
+SvXMLImportContext(i_rImport),
+ScXMLDocContext_Impl(i_rImport, nElement, i_xAttrList),
+SvXMLMetaDocumentContext(i_rImport, nElement, i_xDocProps)
+{
+}
+
 SvXMLImportContext *ScXMLFlatDocContext_Impl::CreateChildContext(
     sal_uInt16 i_nPrefix, const OUString& i_rLocalName,
     const uno::Reference<xml::sax::XAttributeList>& i_xAttrList)
@@ -287,31 +339,54 @@ SvXMLImportContext *ScXMLFlatDocContext_Impl::CreateChildContext(
     }
 }
 
+uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
+    ScXMLFlatDocContext_Impl::createFastChildContext( sal_Int32 nElement,
+    const uno::Reference< xml::sax::XFastAttributeList > & xAttrList )
+    throw (uno::RuntimeException, xml::sax::SAXException, std::exception)
+{
+    if ( nElement != ( NAMESPACE_TOKEN( XML_NAMESPACE_OFFICE ) | XML_META ) )
+        return ScXMLDocContext_Impl::createFastChildContext( nElement, xAttrList );
+    else
+        return new SvXMLImportContext( GetImport() );
+}
+
+void SAL_CALL ScXMLFlatDocContext_Impl::startFastElement(sal_Int32 nElement,
+    const uno::Reference< xml::sax::XFastAttributeList > & xAttrList)
+    throw (uno::RuntimeException, xml::sax::SAXException, std::exception)
+{
+    SvXMLMetaDocumentContext::startFastElement( nElement, xAttrList );
+}
+
+void SAL_CALL ScXMLFlatDocContext_Impl::endFastElement(sal_Int32 nElement)
+    throw (uno::RuntimeException, xml::sax::SAXException, std::exception)
+{
+    SvXMLMetaDocumentContext::endFastElement( nElement );
+}
+
 class ScXMLBodyContext_Impl : public ScXMLImportContext
 {
 public:
-    ScXMLBodyContext_Impl( ScXMLImport& rImport, sal_uInt16 nPrfx,
-        const OUString& rLName,
-        const uno::Reference< xml::sax::XAttributeList > & xAttrList );
+    ScXMLBodyContext_Impl( ScXMLImport& rImport, sal_Int32 nElement,
+        const uno::Reference< xml::sax::XFastAttributeList > & xAttrList );
 
-    virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
-        const OUString& rLocalName,
-        const uno::Reference< xml::sax::XAttributeList > & xAttrList ) override;
+    virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL
+        createFastChildContext( sal_Int32 nElement,
+        const css::uno::Reference<css::xml::sax::XFastAttributeList>& xAttrList )
+        throw (css::uno::RuntimeException, css::xml::sax::SAXException, std::exception ) override;
 };
 
-ScXMLBodyContext_Impl::ScXMLBodyContext_Impl( ScXMLImport& rImport,
-                                             sal_uInt16 nPrfx, const OUString& rLName,
-                                             const uno::Reference< xml::sax::XAttributeList > & /* xAttrList */ ) :
-ScXMLImportContext( rImport, nPrfx, rLName )
+ScXMLBodyContext_Impl::ScXMLBodyContext_Impl( ScXMLImport& rImport, sal_Int32 /*nElement*/,
+                                             const uno::Reference< xml::sax::XFastAttributeList > & /* xAttrList */ ) :
+ScXMLImportContext( rImport )
 {
 }
 
-SvXMLImportContext *ScXMLBodyContext_Impl::CreateChildContext(
-    sal_uInt16 /* nPrefix */,
-    const OUString& rLocalName,
-    const uno::Reference< xml::sax::XAttributeList > & xAttrList )
+uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
+    ScXMLBodyContext_Impl::createFastChildContext( sal_Int32 nElement,
+    const uno::Reference< xml::sax::XFastAttributeList > & xAttrList )
+    throw (uno::RuntimeException, xml::sax::SAXException, std::exception)
 {
-    return GetScImport().CreateBodyContext( rLocalName, xAttrList );
+    return GetScImport().CreateBodyContext( nElement, xAttrList );
 }
 
 SvXMLImportContext *ScXMLDocContext_Impl::CreateChildContext( sal_uInt16 nPrefix,
@@ -347,11 +422,6 @@ SvXMLImportContext *ScXMLDocContext_Impl::CreateChildContext( sal_uInt16 nPrefix
         if (GetScImport().getImportFlags() & SvXMLImportFlags::SCRIPTS)
             pContext = GetScImport().CreateScriptContext( rLocalName );
         break;
-    case XML_TOK_DOC_BODY:
-        if (GetScImport().getImportFlags() & SvXMLImportFlags::CONTENT)
-            pContext = new ScXMLBodyContext_Impl( GetScImport(), nPrefix,
-            rLocalName, xAttrList );
-        break;
     case XML_TOK_DOC_SETTINGS:
         if (GetScImport().getImportFlags() & SvXMLImportFlags::SETTINGS)
             pContext = new XMLDocumentSettingsContext(GetScImport(), nPrefix, rLocalName, xAttrList );
@@ -364,6 +434,49 @@ SvXMLImportContext *ScXMLDocContext_Impl::CreateChildContext( sal_uInt16 nPrefix
     return pContext;
 }
 
+uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
+    ScXMLDocContext_Impl::createFastChildContext( sal_Int32 nElement,
+    const uno::Reference< xml::sax::XFastAttributeList > & xAttrList )
+    throw (uno::RuntimeException, xml::sax::SAXException, std::exception)
+{
+    SvXMLImportContext *pContext(nullptr);
+
+    const SvXMLTokenMap& rTokenMap(GetScImport().GetDocElemTokenMap());
+    switch( rTokenMap.Get( nElement ) )
+    {
+        case XML_TOK_DOC_BODY:
+        if (GetScImport().getImportFlags() & SvXMLImportFlags::CONTENT)
+            pContext = new ScXMLBodyContext_Impl( GetScImport(),
+                                                nElement, xAttrList );
+        break;
+
+        //TODO: handle all other cases
+        default:
+           pContext = new SvXMLImportContext( GetImport() );
+    }
+
+    if(!pContext)
+        pContext = new SvXMLImportContext( GetImport() );
+
+    return pContext;
+}
+
+void SAL_CALL ScXMLDocContext_Impl::startFastElement(sal_Int32 /*nElement*/,
+    const uno::Reference< xml::sax::XFastAttributeList > & /*xAttrList*/)
+    throw (uno::RuntimeException, xml::sax::SAXException, std::exception)
+{
+}
+
+void SAL_CALL ScXMLDocContext_Impl::endFastElement(sal_Int32 /*nElement*/)
+    throw (uno::RuntimeException, xml::sax::SAXException, std::exception)
+{
+}
+
+void SAL_CALL ScXMLDocContext_Impl::characters(const OUString &)
+    throw (uno::RuntimeException, xml::sax::SAXException, std::exception)
+{
+}
+
 const SvXMLTokenMap& ScXMLImport::GetDocElemTokenMap()
 {
     if( !pDocElemTokenMap )
@@ -1928,13 +2041,7 @@ SvXMLImportContext *ScXMLImport::CreateContext( sal_uInt16 nPrefix,
 {
     SvXMLImportContext *pContext = nullptr;
 
-    if( (XML_NAMESPACE_OFFICE == nPrefix) &&
-        ( IsXMLToken(rLocalName, XML_DOCUMENT_STYLES) ||
-        IsXMLToken(rLocalName, XML_DOCUMENT_CONTENT) ||
-        IsXMLToken(rLocalName, XML_DOCUMENT_SETTINGS) )) {
-            pContext = new ScXMLDocContext_Impl( *this, nPrefix, rLocalName,
-                xAttrList );
-    } else if ( (XML_NAMESPACE_OFFICE == nPrefix) &&
+    if ( (XML_NAMESPACE_OFFICE == nPrefix) &&
         ( IsXMLToken(rLocalName, XML_DOCUMENT_META)) ) {
             pContext = CreateMetaContext(rLocalName);
     } else if ( (XML_NAMESPACE_OFFICE == nPrefix) &&
@@ -1951,6 +2058,36 @@ SvXMLImportContext *ScXMLImport::CreateContext( sal_uInt16 nPrefix,
     return pContext;
 }
 
+SvXMLImportContext *ScXMLImport::CreateFastContext( sal_Int32 nElement,
+        const uno::Reference< xml::sax::XFastAttributeList >& xAttrList )
+{
+    SvXMLImportContext *pContext = nullptr;
+
+    switch( nElement )
+    {
+    case ( NAMESPACE_TOKEN( XML_NAMESPACE_OFFICE ) | XML_DOCUMENT_STYLES ):
+    case ( NAMESPACE_TOKEN( XML_NAMESPACE_OFFICE ) | XML_DOCUMENT_CONTENT ):
+    case ( NAMESPACE_TOKEN( XML_NAMESPACE_OFFICE ) | XML_DOCUMENT_SETTINGS ):
+        pContext = new ScXMLDocContext_Impl( *this, nElement, xAttrList );
+        break;
+
+    case ( NAMESPACE_TOKEN( XML_NAMESPACE_OFFICE ) | XML_DOCUMENT ):
+    {
+        uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
+            GetModel(), uno::UNO_QUERY_THROW);
+        // flat OpenDocument file format
+        pContext = new ScXMLFlatDocContext_Impl( *this, nElement,
+            xAttrList, xDPS->getDocumentProperties());
+        break;
+    }
+
+    default:
+        pContext = new SvXMLImportContext( *this );
+    }
+
+    return pContext;
+}
+
 ScXMLImport::ScXMLImport(
     const css::uno::Reference< css::uno::XComponentContext >& rContext,
     OUString const & implementationName, SvXMLImportFlags nImportFlag)
@@ -2241,10 +2378,10 @@ SvXMLImportContext *ScXMLImport::CreateStylesContext(const OUString& rLocalName,
     return pContext;
 }
 
-SvXMLImportContext *ScXMLImport::CreateBodyContext(const OUString& rLocalName,
-                                                   const uno::Reference<xml::sax::XAttributeList>& xAttrList)
+SvXMLImportContext *ScXMLImport::CreateBodyContext(const sal_Int32 nElement,
+                                                   const uno::Reference<xml::sax::XFastAttributeList>& xAttrList)
 {
-    return new ScXMLBodyContext(*this, XML_NAMESPACE_OFFICE, rLocalName, xAttrList);
+    return new ScXMLBodyContext(*this, nElement, xAttrList);
 }
 
 SvXMLImportContext *ScXMLImport::CreateMetaContext(
diff --git a/sc/source/filter/xml/xmlimprt.hxx b/sc/source/filter/xml/xmlimprt.hxx
index 28f9ae9..c09dff5 100644
--- a/sc/source/filter/xml/xmlimprt.hxx
+++ b/sc/source/filter/xml/xmlimprt.hxx
@@ -954,6 +954,10 @@ protected:
     virtual SvXMLImportContext *CreateContext(sal_uInt16 nPrefix,
                                       const OUString& rLocalName,
                                       const css::uno::Reference<css::xml::sax::XAttributeList>& xAttrList ) override;
+
+    virtual SvXMLImportContext *CreateFastContext( sal_Int32 nElement,
+        const ::css::uno::Reference< ::css::xml::sax::XFastAttributeList >& xAttrList ) override;
+
     virtual XMLShapeImportHelper* CreateShapeImport() override;
 
 public:
@@ -979,9 +983,10 @@ public:
     SvXMLImportContext *CreateStylesContext(const OUString& rLocalName,
                                      const css::uno::Reference<css::xml::sax::XAttributeList>& xAttrList,
                                      bool bAutoStyles );
+
     SvXMLImportContext *CreateBodyContext(
-                                    const OUString& rLocalName,
-                                    const css::uno::Reference<css::xml::sax::XAttributeList>& xAttrList );
+                                    const sal_Int32 nElement,
+                                    const css::uno::Reference<css::xml::sax::XFastAttributeList>& xAttrList );
 
     virtual void SetStatistics( const css::uno::Sequence< css::beans::NamedValue> & i_rStats) override;
 
diff --git a/sc/source/filter/xml/xmlrowi.cxx b/sc/source/filter/xml/xmlrowi.cxx
index 2a66bde..1308432 100644
--- a/sc/source/filter/xml/xmlrowi.cxx
+++ b/sc/source/filter/xml/xmlrowi.cxx
@@ -33,6 +33,7 @@
 #include <xmloff/xmlnmspe.hxx>
 #include <xmloff/families.hxx>
 #include <xmloff/xmltoken.hxx>
+#include <sax/fastattribs.hxx>
 #include <com/sun/star/sheet/XSpreadsheet.hpp>
 #include <com/sun/star/table/XColumnRowRange.hpp>
 #include <com/sun/star/sheet/XPrintAreas.hpp>
@@ -43,55 +44,58 @@ using namespace com::sun::star;
 using namespace xmloff::token;
 
 ScXMLTableRowContext::ScXMLTableRowContext( ScXMLImport& rImport,
-                                      sal_uInt16 nPrfx,
-                                      const OUString& rLName,
-                                      const css::uno::Reference<css::xml::sax::XAttributeList>& xAttrList ) :
-    ScXMLImportContext( rImport, nPrfx, rLName ),
+                                      sal_Int32 /*nElement*/,
+                                      const css::uno::Reference<css::xml::sax::XFastAttributeList>& xAttrList ) :
+    ScXMLImportContext( rImport ),
     sVisibility(GetXMLToken(XML_VISIBLE)),
     nRepeatedRows(1),
     bHasCell(false)
 {
     OUString sCellStyleName;
-    sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
     const SvXMLTokenMap& rAttrTokenMap(GetScImport().GetTableRowAttrTokenMap());
-    for( sal_Int16 i=0; i < nAttrCount; ++i )
+    if ( xAttrList.is() )
     {
-        const OUString& sAttrName(xAttrList->getNameByIndex( i ));
-        OUString aLocalName;
-        sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
-                                            sAttrName, &aLocalName ));
-        const OUString& sValue(xAttrList->getValueByIndex( i ));
+        sax_fastparser::FastAttributeList *pAttribList;
+        assert( dynamic_cast< sax_fastparser::FastAttributeList *>( xAttrList.get() ) != nullptr );
+        pAttribList = static_cast< sax_fastparser::FastAttributeList *>( xAttrList.get() );
 
-        switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+        const std::vector< sal_Int32 >& rAttrList = pAttribList->getFastAttributeTokens();
+        for ( size_t i = 0; i < rAttrList.size(); i++ )
         {
-            case XML_TOK_TABLE_ROW_ATTR_STYLE_NAME:
+            const OUString sValue = OUString(pAttribList->getFastAttributeValue(i),
+                                    pAttribList->AttributeValueLength(i), RTL_TEXTENCODING_UTF8);
+            switch( rAttrTokenMap.Get( rAttrList[ i ] ) )
             {
-                sStyleName = sValue;
-            }
-            break;
-            case XML_TOK_TABLE_ROW_ATTR_VISIBILITY:
-            {
-                sVisibility = sValue;
-            }
-            break;
-            case XML_TOK_TABLE_ROW_ATTR_REPEATED:
-            {
-                nRepeatedRows = std::max( sValue.toInt32(), (sal_Int32) 1 );
-                nRepeatedRows = std::min( nRepeatedRows, MAXROWCOUNT );
-            }
-            break;
-            case XML_TOK_TABLE_ROW_ATTR_DEFAULT_CELL_STYLE_NAME:
-            {
-                sCellStyleName = sValue;
-            }
-            break;
-            /*case XML_TOK_TABLE_ROW_ATTR_USE_OPTIMAL_HEIGHT:
-            {
-                sOptimalHeight = sValue;
+                case XML_TOK_TABLE_ROW_ATTR_STYLE_NAME:
+                {
+                    sStyleName = sValue;
+                }
+                break;
+                case XML_TOK_TABLE_ROW_ATTR_VISIBILITY:
+                {
+                    sVisibility = sValue;
+                }
+                break;
+                case XML_TOK_TABLE_ROW_ATTR_REPEATED:
+                {
+                    nRepeatedRows = std::max( sValue.toInt32(), (sal_Int32) 1 );
+                    nRepeatedRows = std::min( nRepeatedRows, MAXROWCOUNT );
+                }
+                break;
+                case XML_TOK_TABLE_ROW_ATTR_DEFAULT_CELL_STYLE_NAME:
+                {
+                    sCellStyleName = sValue;
+                }
+                break;
+                /*case XML_TOK_TABLE_ROW_ATTR_USE_OPTIMAL_HEIGHT:
+                {
+                    sOptimalHeight = sValue;
+                }
+                break;*/
             }
-            break;*/
         }
     }
+
     GetScImport().GetTables().AddRow();
     GetScImport().GetTables().SetRowStyle(sCellStyleName);
 }
@@ -100,21 +104,22 @@ ScXMLTableRowContext::~ScXMLTableRowContext()
 {
 }
 
-SvXMLImportContext *ScXMLTableRowContext::CreateChildContext( sal_uInt16 nPrefix,
-                                            const OUString& rLName,
-                                            const css::uno::Reference<css::xml::sax::XAttributeList>& xAttrList )
+uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
+        ScXMLTableRowContext::createFastChildContext( sal_Int32 nElement,
+        const uno::Reference< xml::sax::XFastAttributeList > & xAttrList )
+        throw (uno::RuntimeException, xml::sax::SAXException, std::exception)
 {
     SvXMLImportContext *pContext(nullptr);
 
     const SvXMLTokenMap& rTokenMap(GetScImport().GetTableRowElemTokenMap());
-    switch( rTokenMap.Get( nPrefix, rLName ) )
+    switch( rTokenMap.Get( nElement ) )
     {
     case XML_TOK_TABLE_ROW_CELL:
 //      if( IsInsertCellPossible() )
         {
             bHasCell = true;
-            pContext = new ScXMLTableRowCellContext( GetScImport(), nPrefix,
-                                                      rLName, xAttrList, false, static_cast<SCROW>(nRepeatedRows)
+            pContext = new ScXMLTableRowCellContext( GetScImport(), nElement,
+                                                       xAttrList, false, static_cast<SCROW>(nRepeatedRows)
                                                       //this
                                                       );
         }
@@ -123,8 +128,8 @@ SvXMLImportContext *ScXMLTableRowContext::CreateChildContext( sal_uInt16 nPrefix
 //      if( IsInsertCellPossible() )
         {
             bHasCell = true;
-            pContext = new ScXMLTableRowCellContext( GetScImport(), nPrefix,
-                                                      rLName, xAttrList, true, static_cast<SCROW>(nRepeatedRows)
+            pContext = new ScXMLTableRowCellContext( GetScImport(), nElement,
+                                                      xAttrList, true, static_cast<SCROW>(nRepeatedRows)
                                                       //this
                                                       );
         }
@@ -132,12 +137,13 @@ SvXMLImportContext *ScXMLTableRowContext::CreateChildContext( sal_uInt16 nPrefix
     }
 
     if( !pContext )
-        pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+        pContext = new SvXMLImportContext( GetImport() );
 
     return pContext;
 }
 
-void ScXMLTableRowContext::EndElement()
+void SAL_CALL ScXMLTableRowContext::endFastElement(sal_Int32 /*nElement*/)
+    throw (uno::RuntimeException, xml::sax::SAXException, std::exception)
 {
     ScXMLImport& rXMLImport(GetScImport());
     if (!bHasCell && nRepeatedRows > 1)
@@ -209,12 +215,11 @@ void ScXMLTableRowContext::EndElement()
 }
 
 ScXMLTableRowsContext::ScXMLTableRowsContext( ScXMLImport& rImport,
-                                      sal_uInt16 nPrfx,
-                                      const OUString& rLName,
-                                      const css::uno::Reference<css::xml::sax::XAttributeList>& xAttrList,
+                                      sal_Int32 /*nElement*/,
+                                      const css::uno::Reference<css::xml::sax::XFastAttributeList>& xAttrList,
                                       const bool bTempHeader,
                                       const bool bTempGroup ) :
-    ScXMLImportContext( rImport, nPrfx, rLName ),
+    ScXMLImportContext( rImport ),
     nHeaderStartRow(0),
     nGroupStartRow(0),
     bHeader(bTempHeader),
@@ -232,17 +237,11 @@ ScXMLTableRowsContext::ScXMLTableRowsContext( ScXMLImport& rImport,
     {
         nGroupStartRow = rImport.GetTables().GetCurrentRow();
         ++nGroupStartRow;
-        sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
-        for( sal_Int16 i=0; i < nAttrCount; ++i )
+        if ( xAttrList.is() &&
+            xAttrList->hasAttribute( NAMESPACE_TOKEN( XML_NAMESPACE_TABLE ) | XML_DISPLAY ) )
         {
-            const OUString& sAttrName(xAttrList->getNameByIndex( i ));
-            OUString aLocalName;
-            sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
-                                                sAttrName, &aLocalName ));
-            const OUString& sValue(xAttrList->getValueByIndex( i ));
-
-            if ((nPrefix == XML_NAMESPACE_TABLE) && IsXMLToken(aLocalName, XML_DISPLAY))
-                bGroupDisplay = IsXMLToken(sValue, XML_TRUE);
+            bGroupDisplay = IsXMLToken( xAttrList->getValue(
+                                NAMESPACE_TOKEN( XML_NAMESPACE_TABLE ) | XML_DISPLAY ), XML_TRUE );
         }
     }
 }
@@ -251,45 +250,44 @@ ScXMLTableRowsContext::~ScXMLTableRowsContext()
 {
 }
 
-SvXMLImportContext *ScXMLTableRowsContext::CreateChildContext( sal_uInt16 nPrefix,
-                                            const OUString& rLName,
-                                            const css::uno::Reference<css::xml::sax::XAttributeList>& xAttrList )
+uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
+        ScXMLTableRowsContext::createFastChildContext( sal_Int32 nElement,
+        const uno::Reference< xml::sax::XFastAttributeList > & xAttrList )
+        throw (uno::RuntimeException, xml::sax::SAXException, std::exception)
 {
     SvXMLImportContext *pContext(nullptr);
 
     const SvXMLTokenMap& rTokenMap(GetScImport().GetTableRowsElemTokenMap());
-    switch( rTokenMap.Get( nPrefix, rLName ) )
+    switch( rTokenMap.Get( nElement ) )
     {
     case XML_TOK_TABLE_ROWS_ROW_GROUP:
-        pContext = new ScXMLTableRowsContext( GetScImport(), nPrefix,
-                                                   rLName, xAttrList,
+        pContext = new ScXMLTableRowsContext( GetScImport(), nElement, xAttrList,
                                                    false, true );
         break;
     case XML_TOK_TABLE_ROWS_HEADER_ROWS:
-        pContext = new ScXMLTableRowsContext( GetScImport(), nPrefix,
-                                                   rLName, xAttrList,
+        pContext = new ScXMLTableRowsContext( GetScImport(), nElement, xAttrList,
                                                    true, false );
         break;
     case XML_TOK_TABLE_ROWS_ROWS:
-        pContext = new ScXMLTableRowsContext( GetScImport(), nPrefix,
-                                                   rLName, xAttrList,
+        pContext = new ScXMLTableRowsContext( GetScImport(), nElement, xAttrList,
                                                    false, false );
         break;
     case XML_TOK_TABLE_ROWS_ROW:
-            pContext = new ScXMLTableRowContext( GetScImport(), nPrefix,
-                                                      rLName, xAttrList//,
+            pContext = new ScXMLTableRowContext( GetScImport(), nElement,
+                                                      xAttrList//,
                                                       //this
                                                       );
         break;
     }
 
     if( !pContext )
-        pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
+        pContext = new SvXMLImportContext( GetImport() );
 
     return pContext;
 }
 
-void ScXMLTableRowsContext::EndElement()
+void SAL_CALL ScXMLTableRowsContext::endFastElement(sal_Int32 /*nElement*/)
+    throw (uno::RuntimeException, xml::sax::SAXException, std::exception)
 {
     ScXMLImport& rXMLImport(GetScImport());
     if (bHeader)
diff --git a/sc/source/filter/xml/xmlrowi.hxx b/sc/source/filter/xml/xmlrowi.hxx
index ea84e9c..5c3ab29 100644
--- a/sc/source/filter/xml/xmlrowi.hxx
+++ b/sc/source/filter/xml/xmlrowi.hxx
@@ -35,17 +35,18 @@ class ScXMLTableRowContext : public ScXMLImportContext
 
 public:
 
-    ScXMLTableRowContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
-                       const OUString& rLName,
-                       const css::uno::Reference<css::xml::sax::XAttributeList>& xAttrList );
+    ScXMLTableRowContext( ScXMLImport& rImport, sal_Int32 nElement,
+                       const css::uno::Reference<css::xml::sax::XFastAttributeList>& xAttrList );
 
     virtual ~ScXMLTableRowContext() override;
 
-    virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
-                                     const OUString& rLocalName,
-                                     const css::uno::Reference<css::xml::sax::XAttributeList>& xAttrList ) override;
+    virtual void SAL_CALL endFastElement(sal_Int32 nElement)
+        throw (css::uno::RuntimeException, css::xml::sax::SAXException, std::exception) override;
 
-    virtual void EndElement() override;
+    virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL
+        createFastChildContext( sal_Int32 nElement,
+        const css::uno::Reference<css::xml::sax::XFastAttributeList>& xAttrList )
+        throw (css::uno::RuntimeException, css::xml::sax::SAXException, std::exception ) override;
 };
 
 class ScXMLTableRowsContext : public ScXMLImportContext
@@ -58,18 +59,20 @@ class ScXMLTableRowsContext : public ScXMLImportContext
 
 public:
 
-    ScXMLTableRowsContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
-                       const OUString& rLName,
-                       const css::uno::Reference<css::xml::sax::XAttributeList>& xAttrList,
+    ScXMLTableRowsContext( ScXMLImport& rImport, sal_Int32 nElement,
+                       const css::uno::Reference<css::xml::sax::XFastAttributeList>& xAttrList,
                        const bool bHeader, const bool bGroup);
 
     virtual ~ScXMLTableRowsContext() override;
 
-    virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
-                                     const OUString& rLocalName,
-                                     const css::uno::Reference<css::xml::sax::XAttributeList>& xAttrList ) override;
+    virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL
+                        createFastChildContext( sal_Int32 nElement,
+                        const css::uno::Reference<css::xml::sax::XFastAttributeList>& xAttrList )
+                        throw (css::uno::RuntimeException, css::xml::sax::SAXException, std::exception ) override;
+
+    virtual void SAL_CALL endFastElement(sal_Int32 nElement)
+                        throw (css::uno::RuntimeException, css::xml::sax::SAXException, std::exception) override;
 
-    virtual void EndElement() override;
 };
 
 #endif
diff --git a/sc/source/filter/xml/xmltabi.cxx b/sc/source/filter/xml/xmltabi.cxx
index 162bacd..6093c52 100644
--- a/sc/source/filter/xml/xmltabi.cxx
+++ b/sc/source/filter/xml/xmltabi.cxx
@@ -42,6 +42,7 @@
 #include <xmloff/XMLEventsImportContext.hxx>
 
 #include <tools/urlobj.hxx>
+#include <sax/fastattribs.hxx>
 
 using namespace com::sun::star;
 using namespace xmloff::token;
@@ -129,10 +130,9 @@ ScXMLExternalTabData::ScXMLExternalTabData() :
 }
 
 ScXMLTableContext::ScXMLTableContext( ScXMLImport& rImport,
-                                      sal_uInt16 nPrfx,
-                                      const OUString& rLName,
-                                      const css::uno::Reference<css::xml::sax::XAttributeList>& xAttrList ) :
-    ScXMLImportContext( rImport, nPrfx, rLName ),
+                                      sal_Int32 /*nElement*/,
+                                      const css::uno::Reference<css::xml::sax::XFastAttributeList>& xAttrList ) :
+    ScXMLImportContext( rImport ),
     nStartOffset(-1),
     bStartFormPage(false),
     bPrintEntireSheet(true)
@@ -143,45 +143,50 @@ ScXMLTableContext::ScXMLTableContext( ScXMLImport& rImport,
     ScXMLTabProtectionData aProtectData;
     OUString sName;
     OUString sStyleName;
-    sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
-    const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetTableAttrTokenMap();
-    for( sal_Int16 i=0; i < nAttrCount; ++i )
+
+    if ( xAttrList.is() )
     {
-        const OUString& sAttrName(xAttrList->getNameByIndex( i ));
-        OUString aLocalName;
-        sal_uInt16 nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
-                                            sAttrName, &aLocalName ));
-        const OUString& sValue(xAttrList->getValueByIndex( i ));
+        sax_fastparser::FastAttributeList *pAttribList;
+        assert( dynamic_cast< sax_fastparser::FastAttributeList *>( xAttrList.get() ) != nullptr );
+        pAttribList = static_cast< sax_fastparser::FastAttributeList *>( xAttrList.get() );
 
-        switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
+        const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetTableAttrTokenMap();
+        const std::vector< sal_Int32 >& rAttrList = pAttribList->getFastAttributeTokens();
+        for ( size_t i = 0; i < rAttrList.size(); i++ )
         {
-            case XML_TOK_TABLE_NAME:
-                    sName = sValue;
+            const OUString sValue = OUString(pAttribList->getFastAttributeValue(i),
+                                    pAttribList->AttributeValueLength(i), RTL_TEXTENCODING_UTF8);
+            switch( rAttrTokenMap.Get( rAttrList[ i ] ) )
+            {
+                case XML_TOK_TABLE_NAME:
+                        sName = sValue;
+                    break;
+                case XML_TOK_TABLE_STYLE_NAME:
+                        sStyleName = sValue;
+                    break;
+                case XML_TOK_TABLE_PROTECTED:
+                    aProtectData.mbProtected = IsXMLToken(sValue, XML_TRUE);
                 break;
-            case XML_TOK_TABLE_STYLE_NAME:
-                    sStyleName = sValue;
+                case XML_TOK_TABLE_PRINT_RANGES:
+                        sPrintRanges = sValue;
+                    break;
+                case XML_TOK_TABLE_PASSWORD:
+                    aProtectData.maPassword = sValue;
                 break;
-            case XML_TOK_TABLE_PROTECTED:
-                aProtectData.mbProtected = IsXMLToken(sValue, XML_TRUE);
-            break;
-            case XML_TOK_TABLE_PRINT_RANGES:
-                    sPrintRanges = sValue;
+                case XML_TOK_TABLE_PASSHASH:
+                    aProtectData.meHash1 = ScPassHashHelper::getHashTypeFromURI( sValue );
                 break;
-            case XML_TOK_TABLE_PASSWORD:
-                aProtectData.maPassword = sValue;
-            break;
-            case XML_TOK_TABLE_PASSHASH:
-                aProtectData.meHash1 = ScPassHashHelper::getHashTypeFromURI(sValue);
-            break;
-            case XML_TOK_TABLE_PASSHASH_2:
-                aProtectData.meHash2 = ScPassHashHelper::getHashTypeFromURI(sValue);
-            break;
-            case XML_TOK_TABLE_PRINT:
-                {
-                    if (IsXMLToken(sValue, XML_FALSE))
-                        bPrintEntireSheet = false;
-                }
+                case XML_TOK_TABLE_PASSHASH_2:
+                    aProtectData.meHash2 = ScPassHashHelper::getHashTypeFromURI( sValue );
                 break;
+                case XML_TOK_TABLE_PRINT:
+                    {
+                        if (IsXMLToken(sValue, XML_FALSE))
+                            bPrintEntireSheet = false;
+                    }
+                    break;
+            }
+
         }
     }
 
@@ -278,27 +283,6 @@ SvXMLImportContext *ScXMLTableContext::CreateChildContext( sal_uInt16 nPrefix,
     case XML_TOK_TABLE_PROTECTION_EXT:
         pContext = new ScXMLTableProtectionContext( GetScImport(), nPrefix, rLName, xAttrList );
         break;
-    case XML_TOK_TABLE_ROW_GROUP:
-        pContext = new ScXMLTableRowsContext( GetScImport(), nPrefix,
-                                                   rLName, xAttrList,
-                                                   false, true );
-        break;
-    case XML_TOK_TABLE_HEADER_ROWS:
-        pContext = new ScXMLTableRowsContext( GetScImport(), nPrefix,
-                                                   rLName, xAttrList,
-                                                   true, false );
-        break;
-    case XML_TOK_TABLE_ROWS:
-        pContext = new ScXMLTableRowsContext( GetScImport(), nPrefix,
-                                                   rLName, xAttrList,
-                                                   false, false );
-        break;
-    case XML_TOK_TABLE_ROW:
-            pContext = new ScXMLTableRowContext( GetScImport(), nPrefix,
-                                                      rLName, xAttrList//,
-                                                      //this
-                                                      );
-        break;
     case XML_TOK_TABLE_SOURCE:
         pContext = new ScXMLTableSourceContext( GetScImport(), nPrefix, rLName, xAttrList);
         break;
@@ -336,7 +320,52 @@ SvXMLImportContext *ScXMLTableContext::CreateChildContext( sal_uInt16 nPrefix,
     return pContext;
 }
 
-void ScXMLTableContext::EndElement()
+uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
+        ScXMLTableContext::createFastChildContext( sal_Int32 nElement,
+        const uno::Reference< xml::sax::XFastAttributeList > & xAttrList )
+        throw (uno::RuntimeException, xml::sax::SAXException, std::exception)
+{
+    const SvXMLTokenMap& rTokenMap(GetScImport().GetTableElemTokenMap());
+    sal_uInt16 nToken = rTokenMap.Get( nElement );
+    if (pExternalRefInfo.get())
+    {
+        return new SvXMLImportContext( GetImport() );
+    }
+
+    SvXMLImportContext *pContext(nullptr);
+
+    switch (nToken)
+    {
+    case XML_TOK_TABLE_ROW_GROUP:
+        pContext = new ScXMLTableRowsContext( GetScImport(), nElement, xAttrList,
+                                                   false, true );
+        break;
+    case XML_TOK_TABLE_HEADER_ROWS:
+        pContext = new ScXMLTableRowsContext( GetScImport(), nElement, xAttrList,
+                                                   true, false );
+        break;
+    case XML_TOK_TABLE_ROWS:
+        pContext = new ScXMLTableRowsContext( GetScImport(), nElement, xAttrList,
+                                                   false, false );
+        break;
+    case XML_TOK_TABLE_ROW:
+            pContext = new ScXMLTableRowContext( GetScImport(), nElement,
+                                                      xAttrList//,
+                                                      //this
+                                                      );
+        break;
+    default:
+        pContext = new SvXMLImportContext( GetImport() );
+    }
+
+    if( !pContext )
+        pContext = new SvXMLImportContext( GetImport() );
+
+    return pContext;
+}
+
+void SAL_CALL ScXMLTableContext::endFastElement(sal_Int32 /*nElement*/)
+    throw (uno::RuntimeException, xml::sax::SAXException, std::exception)
 {
     ScXMLImport::MutexGuard aMutexGuard(GetScImport());
     ScXMLImport& rImport = GetScImport();
diff --git a/sc/source/filter/xml/xmltabi.hxx b/sc/source/filter/xml/xmltabi.hxx
index a42ecb4..0dfa46d 100644
--- a/sc/source/filter/xml/xmltabi.hxx
+++ b/sc/source/filter/xml/xmltabi.hxx
@@ -48,9 +48,8 @@ class ScXMLTableContext : public ScXMLImportContext
 
 public:
 
-    ScXMLTableContext( ScXMLImport& rImport, sal_uInt16 nPrfx,
-                        const OUString& rLName,
-                        const css::uno::Reference<css::xml::sax::XAttributeList>& xAttrList );
+    ScXMLTableContext( ScXMLImport& rImport, sal_Int32 nElement,
+                        const css::uno::Reference<css::xml::sax::XFastAttributeList>& xAttrList );
 
     virtual ~ScXMLTableContext() override;
 
@@ -58,7 +57,13 @@ public:
                                      const OUString& rLocalName,
                                      const css::uno::Reference<css::xml::sax::XAttributeList>& xAttrList ) override;
 
-    virtual void EndElement() override;
+    virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL
+        createFastChildContext( sal_Int32 nElement,
+        const css::uno::Reference<css::xml::sax::XFastAttributeList>& xAttrList )
+        throw (css::uno::RuntimeException, css::xml::sax::SAXException, std::exception ) override;
+
+    virtual void SAL_CALL endFastElement(sal_Int32 nElement)
+        throw (css::uno::RuntimeException, css::xml::sax::SAXException, std::exception) override;
 };
 
 class ScXMLTableProtectionContext : public ScXMLImportContext
diff --git a/sc/source/filter/xml/xmlwrap.cxx b/sc/source/filter/xml/xmlwrap.cxx
index c6b8be1..ed56083 100644
--- a/sc/source/filter/xml/xmlwrap.cxx
+++ b/sc/source/filter/xml/xmlwrap.cxx
@@ -34,6 +34,7 @@
 #include <com/sun/star/beans/XPropertySetInfo.hpp>
 #include <com/sun/star/xml/sax/InputSource.hpp>
 #include <com/sun/star/xml/sax/Parser.hpp>
+#include <com/sun/star/xml/sax/XFastParser.hpp>
 #include <com/sun/star/xml/sax/Writer.hpp>
 #include <com/sun/star/frame/XModel.hpp>
 #include <com/sun/star/beans/PropertyAttribute.hpp>
@@ -172,11 +173,16 @@ sal_uInt32 ScXMLImportWrapper::ImportFromComponent(const uno::Reference<uno::XCo
         pImporterImpl->SetPostProcessData(&maPostProcessData);
 
     // connect parser and filter
+    uno::Reference< xml::sax::XFastParser > xFastParser = dynamic_cast<
+                            xml::sax::XFastParser* >( xDocHandler.get() );
     xParser->setDocumentHandler( xDocHandler );
 
     try
     {
-        xParser->parseStream( aParserInput );
+        if( xFastParser.is() )
+            xFastParser->parseStream( aParserInput );
+        else
+            xParser->parseStream( aParserInput );
     }
     catch( const xml::sax::SAXParseException& r )
     {
diff --git a/xmloff/Library_xof.mk b/xmloff/Library_xof.mk
index 9305128..202a9c2 100644
--- a/xmloff/Library_xof.mk
+++ b/xmloff/Library_xof.mk
@@ -26,6 +26,10 @@ $(eval $(call gb_Library_set_include,xof,\
     $$(INCLUDE) \
 ))
 
+$(eval $(call gb_Library_use_custom_headers,xof,\
+	xmloff/generated \
+))
+
 $(eval $(call gb_Library_set_precompiled_header,xof,$(SRCDIR)/xmloff/inc/pch/precompiled_xof))
 
 $(eval $(call gb_Library_use_external,xof,boost_headers))
diff --git a/xmloff/source/core/xmlictxt.cxx b/xmloff/source/core/xmlictxt.cxx
index 4a63be9..05a6c45 100644
--- a/xmloff/source/core/xmlictxt.cxx
+++ b/xmloff/source/core/xmlictxt.cxx
@@ -147,7 +147,11 @@ uno::Reference< xml::sax::XFastContextHandler > SAL_CALL SvXMLImportContext::cre
     (sal_Int32 Element, const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
     throw (uno::RuntimeException, xml::sax::SAXException, std::exception)
 {
-    return mrImport.CreateFastContext( Element, Attribs );
+    // Call CreateFastContext only if it's the first element of the document
+    if ( !mrImport.maFastContexts.size() )
+        return mrImport.CreateFastContext( Element, Attribs );
+    else
+        return new SvXMLImportContext( GetImport() );
 }
 
 uno::Reference< xml::sax::XFastContextHandler > SAL_CALL SvXMLImportContext::createUnknownChildContext
diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx
index ed6e22d..9aefba0 100644
--- a/xmloff/source/core/xmltoken.cxx
+++ b/xmloff/source/core/xmltoken.cxx
@@ -577,6 +577,8 @@ namespace xmloff { namespace token {
         TOKEN( "date-adjust",                     XML_DATE_ADJUST ),
         TOKEN( "date-style",                      XML_DATE_STYLE ),
         TOKEN( "date-time",                       XML_DATE_TIME ),
+        TOKEN( "date-time-update",                XML_DATE_TIME_UPDATE ),
+        TOKEN( "date-time-visible",               XML_DATE_TIME_VISIBLE ),
         TOKEN( "date-value",                      XML_DATE_VALUE ),
         TOKEN( "datetime",                        XML_DATETIME ),
         TOKEN( "day",                             XML_DAY ),
@@ -848,6 +850,7 @@ namespace xmloff { namespace token {
         TOKEN( "footer-first",                    XML_FOOTER_FIRST ),
         TOKEN( "footer-left",                     XML_FOOTER_LEFT ),
         TOKEN( "footer-style",                    XML_FOOTER_STYLE ),
+        TOKEN( "footer-visible",                  XML_FOOTER_VISIBLE ),
         TOKEN( "footnote",                        XML_FOOTNOTE ),
         TOKEN( "footnote-body",                   XML_FOOTNOTE_BODY ),
         TOKEN( "footnote-citation",               XML_FOOTNOTE_CITATION ),
@@ -1381,6 +1384,7 @@ namespace xmloff { namespace token {
         TOKEN( "page-master-name",                XML_PAGE_MASTER_NAME ),
         TOKEN( "page-name",                       XML_PAGE_NAME ),
         TOKEN( "page-number",                     XML_PAGE_NUMBER ),
+        TOKEN( "page-number-visible",             XML_PAGE_NUMBER_VISIBLE ),
         TOKEN( "page-start-margin",               XML_PAGE_START_MARGIN ),
         TOKEN( "page-style-name",                 XML_PAGE_STYLE_NAME ),
         TOKEN( "page-thumbnail",                  XML_PAGE_THUMBNAIL ),
diff --git a/xmloff/source/meta/xmlmetai.cxx b/xmloff/source/meta/xmlmetai.cxx
index 0a39e72..459f3cf 100644
--- a/xmloff/source/meta/xmlmetai.cxx
+++ b/xmloff/source/meta/xmlmetai.cxx
@@ -162,6 +162,19 @@ SvXMLMetaDocumentContext::SvXMLMetaDocumentContext(SvXMLImport& rImport,
 //    OSL_ENSURE(xDocProps.is(), "SvXMLMetaDocumentContext: no document props");
 }
 
+SvXMLMetaDocumentContext::SvXMLMetaDocumentContext(SvXMLImport& rImport,
+            sal_Int32 /*nElement*/,
+            const uno::Reference<document::XDocumentProperties>& xDocProps) :
+    SvXMLImportContext( rImport ),
+    mxDocProps(xDocProps),
+    mxDocBuilder(
+        xml::dom::SAXDocumentBuilder::create(
+            comphelper::getProcessComponentContext()))
+{
+// #i103539#: must always read meta.xml for generator, xDocProps unwanted then
+//    OSL_ENSURE(xDocProps.is(), "SvXMLMetaDocumentContext: no document props");
+}
+
 SvXMLMetaDocumentContext::~SvXMLMetaDocumentContext()
 {
 }
diff --git a/xmloff/source/token/tokens.txt b/xmloff/source/token/tokens.txt
index 1a1db7b..3c9d083 100644
--- a/xmloff/source/token/tokens.txt
+++ b/xmloff/source/token/tokens.txt
@@ -499,6 +499,8 @@ date-is
 date-adjust
 date-style
 date-time
+date-time-update
+date-time-visible
 date-value
 datetime
 day
@@ -770,6 +772,7 @@ footer
 footer-first
 footer-left
 footer-style
+footer-visible
 footnote
 footnote-body
 footnote-citation
@@ -1298,6 +1301,7 @@ page-master
 page-master-name
 page-name
 page-number
+page-number-visible
 page-start-margin
 page-style-name
 page-thumbnail
diff --git a/xmloff/source/transform/ChartPlotAreaOASISTContext.cxx b/xmloff/source/transform/ChartPlotAreaOASISTContext.cxx
index 18733301..ddd022e 100644
--- a/xmloff/source/transform/ChartPlotAreaOASISTContext.cxx
+++ b/xmloff/source/transform/ChartPlotAreaOASISTContext.cxx
@@ -167,11 +167,11 @@ void XMLAxisOASISContext::EndElement()
                                     XML_CATEGORY ), "Axis Dimension: invalid new value" );
         }
 
-        GetTransformer().GetDocHandler()->startElement(
+        GetTransformer().startFastElement(
             GetExportQName(),
             Reference< xml::sax::XAttributeList >( pMutableAttrList ));
         ExportContent();
-        GetTransformer().GetDocHandler()->endElement( GetExportQName());
+        GetTransformer().endFastElement( GetExportQName());
     }
     else
         Export();
diff --git a/xmloff/source/transform/ControlOASISTContext.cxx b/xmloff/source/transform/ControlOASISTContext.cxx
index 3b5ece6..f5940a2 100644
--- a/xmloff/source/transform/ControlOASISTContext.cxx
+++ b/xmloff/source/transform/ControlOASISTContext.cxx
@@ -135,7 +135,7 @@ void XMLControlOASISTransformerContext::StartElement(
     }
 
     if( m_bCreateControl )
-        GetTransformer().GetDocHandler()->startElement( m_aElemQName,
+        GetTransformer().startFastElement( m_aElemQName,
                                                         xControlAttrList );
     XMLTransformerContext::StartElement( xAttrList );
 }
@@ -144,7 +144,7 @@ void XMLControlOASISTransformerContext::EndElement()
 {
     XMLTransformerContext::EndElement();
     if( m_bCreateControl )
-        GetTransformer().GetDocHandler()->endElement( m_aElemQName );
+        GetTransformer().endFastElement( m_aElemQName );
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/transform/ControlOOoTContext.cxx b/xmloff/source/transform/ControlOOoTContext.cxx
index b37a734..9f42d35 100644
--- a/xmloff/source/transform/ControlOOoTContext.cxx
+++ b/xmloff/source/transform/ControlOOoTContext.cxx
@@ -63,7 +63,7 @@ rtl::Reference<XMLTransformerContext> XMLControlOOoTransformerContext::CreateChi
         GetTransformer().ProcessAttrList( m_xAttrList,
                                           OOO_FORM_CONTROL_ACTIONS,
                                           false );
-        GetTransformer().GetDocHandler()->startElement( m_aElemQName,
+        GetTransformer().startFastElement( m_aElemQName,
                                                         m_xAttrList );
     }
     else
@@ -77,7 +77,7 @@ rtl::Reference<XMLTransformerContext> XMLControlOOoTransformerContext::CreateChi
 
 void XMLControlOOoTransformerContext::EndElement()
 {
-    GetTransformer().GetDocHandler()->endElement( m_aElemQName );
+    GetTransformer().endFastElement( m_aElemQName );
 }
 
 void XMLControlOOoTransformerContext::Characters( const OUString& rChars )
diff --git a/xmloff/source/transform/EventOOoTContext.cxx b/xmloff/source/transform/EventOOoTContext.cxx
index 42cc1ab..264bc12 100644
--- a/xmloff/source/transform/EventOOoTContext.cxx
+++ b/xmloff/source/transform/EventOOoTContext.cxx
@@ -209,8 +209,7 @@ void XMLEventOOoTransformerContext::StartElement(
     if( m_bPersistent )
         XMLPersElemContentTContext::StartElement( xAttrList );
     else
-        GetTransformer().GetDocHandler()->startElement( GetExportQName(),
-                                                        xAttrList );
+        GetTransformer().startFastElement( GetExportQName(), xAttrList );
 }
 
 void XMLEventOOoTransformerContext::EndElement()
@@ -218,7 +217,7 @@ void XMLEventOOoTransformerContext::EndElement()
     if( m_bPersistent )
         XMLPersElemContentTContext::EndElement();
     else
-        GetTransformer().GetDocHandler()->endElement( GetExportQName() );
+        GetTransformer().endFastElement( GetExportQName() );
 }
 
 rtl::Reference<XMLTransformerContext> XMLEventOOoTransformerContext::CreateChildContext(
diff --git a/xmloff/source/transform/FormPropOASISTContext.cxx b/xmloff/source/transform/FormPropOASISTContext.cxx
index 2e68b23..ab46e81 100644
--- a/xmloff/source/transform/FormPropOASISTContext.cxx
+++ b/xmloff/source/transform/FormPropOASISTContext.cxx
@@ -196,10 +196,10 @@ void XMLFormPropOASISTransformerContext::StartElement(
         OUString aValueElemQName(
             GetTransformer().GetNamespaceMap().GetQNameByKey(
                     XML_NAMESPACE_FORM, GetXMLToken( XML_PROPERTY_VALUE ) ) );
-        GetTransformer().GetDocHandler()->startElement( aValueElemQName,
+        GetTransformer().startFastElement( aValueElemQName,
                                                         xAttrList );
         GetTransformer().GetDocHandler()->characters( aValue );
-        GetTransformer().GetDocHandler()->endElement( aValueElemQName );
+        GetTransformer().endFastElement( aValueElemQName );
     }
 }
 
diff --git a/xmloff/source/transform/FormPropOOoTContext.cxx b/xmloff/source/transform/FormPropOOoTContext.cxx
index 61ac282..b590d06 100644
--- a/xmloff/source/transform/FormPropOOoTContext.cxx
+++ b/xmloff/source/transform/FormPropOOoTContext.cxx
@@ -243,9 +243,8 @@ void XMLFormPropOOoTransformerContext::EndElement()
                                 GetXMLToken( m_eValueTypeToken ) );
     }
 
-    GetTransformer().GetDocHandler()->startElement( m_aElemQName,
-                                                    m_xAttrList );
-    GetTransformer().GetDocHandler()->endElement( m_aElemQName );
+    GetTransformer().startFastElement( m_aElemQName, m_xAttrList );
+    GetTransformer().endFastElement( m_aElemQName );
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/transform/FrameOASISTContext.cxx b/xmloff/source/transform/FrameOASISTContext.cxx
index ca5b1e9..4ed0d0a 100644
--- a/xmloff/source/transform/FrameOASISTContext.cxx
+++ b/xmloff/source/transform/FrameOASISTContext.cxx
@@ -145,8 +145,7 @@ rtl::Reference<XMLTransformerContext> XMLFrameOASISTransformerContext::CreateChi
                     GetTransformer().ProcessAttrList( m_xAttrList,
                                                       OASIS_SHAPE_ACTIONS,
                                                       false );
-                    GetTransformer().GetDocHandler()->startElement( m_aElemQName,
-                                                                    m_xAttrList );
+                    GetTransformer().startFastElement( m_aElemQName, m_xAttrList );
                 }
                 else
                 {
@@ -175,7 +174,7 @@ rtl::Reference<XMLTransformerContext> XMLFrameOASISTransformerContext::CreateChi
 void XMLFrameOASISTransformerContext::EndElement()
 {
     if( !m_bIgnoreElement )
-        GetTransformer().GetDocHandler()->endElement( m_aElemQName );
+        GetTransformer().endFastElement( m_aElemQName );
 }
 
 void XMLFrameOASISTransformerContext::Characters( const OUString& rChars )
diff --git a/xmloff/source/transform/FrameOOoTContext.cxx b/xmloff/source/transform/FrameOOoTContext.cxx
index 0176964..8c66584 100644
--- a/xmloff/source/transform/FrameOOoTContext.cxx
+++ b/xmloff/source/transform/FrameOOoTContext.cxx
@@ -91,7 +91,7 @@ void XMLFrameOOoTransformerContext::StartElement(
         }
     }
 
-    GetTransformer().GetDocHandler()->startElement( m_aElemQName,
+    GetTransformer().startFastElement( m_aElemQName,
                                                     xFrameAttrList );
     XMLTransformerContext::StartElement( xAttrList );
 }
@@ -140,7 +140,7 @@ void XMLFrameOOoTransformerContext::EndElement()
 {
     XMLTransformerContext::EndElement();
     ExportContent();
-    GetTransformer().GetDocHandler()->endElement( m_aElemQName );
+    GetTransformer().endFastElement( m_aElemQName );
 }
 
 void XMLFrameOOoTransformerContext::Characters( const OUString& rChars )
diff --git a/xmloff/source/transform/MetaTContext.cxx b/xmloff/source/transform/MetaTContext.cxx
index 0e4969c..e22b51d 100644
--- a/xmloff/source/transform/MetaTContext.cxx
+++ b/xmloff/source/transform/MetaTContext.cxx
@@ -101,7 +101,7 @@ void XMLMetaTransformerContext::EndElement()
 
                 Reference< XAttributeList > xAttrList =
                     new XMLMutableAttributeList;
-                GetTransformer().GetDocHandler()->startElement( aKeywordsQName,
+                GetTransformer().startFastElement( aKeywordsQName,
                                                             xAttrList );
             }
 
@@ -115,12 +115,12 @@ void XMLMetaTransformerContext::EndElement()
             }
 
             if( XML_KEYWORD == *pToken )
-                GetTransformer().GetDocHandler()->endElement( aKeywordsQName );
+                GetTransformer().endFastElement( aKeywordsQName );
         }
         pToken++;
     }
 
-    GetTransformer().GetDocHandler()->endElement( GetQName() );
+    GetTransformer().endFastElement( GetQName() );
 }
 
 void XMLMetaTransformerContext::Characters( const OUString& )
diff --git a/xmloff/source/transform/NotesTContext.cxx b/xmloff/source/transform/NotesTContext.cxx
index bef8abc..b28115f 100644
--- a/xmloff/source/transform/NotesTContext.cxx
+++ b/xmloff/source/transform/NotesTContext.cxx
@@ -137,7 +137,7 @@ void XMLNotesTransformerContext::StartElement(
     if( m_bPersistent )
         XMLPersElemContentTContext::StartElement( xAttrList );
     else
-        GetTransformer().GetDocHandler()->startElement( GetExportQName(),
+        GetTransformer().startFastElement( GetExportQName(),
                                                         xAttrList );
 }
 
@@ -149,7 +149,7 @@ void XMLNotesTransformerContext::EndElement()
     }
     else
     {
-        GetTransformer().GetDocHandler()->endElement( GetExportQName() );
+        GetTransformer().endFastElement( GetExportQName() );
     }
 }
 
diff --git a/xmloff/source/transform/OOo2Oasis.cxx b/xmloff/source/transform/OOo2Oasis.cxx
index c6cc7c4..e5e188e 100644
--- a/xmloff/source/transform/OOo2Oasis.cxx
+++ b/xmloff/source/transform/OOo2Oasis.cxx
@@ -1213,12 +1213,12 @@ void XMLDocumentTransformerContext_Impl::StartElement(
                         XML_NAMESPACE_SVG ) );
     }
 
-    GetTransformer().GetDocHandler()->startElement( m_aElemQName, xAttrList );
+    GetTransformer().startFastElement( m_aElemQName, xAttrList );
 }
 
 void XMLDocumentTransformerContext_Impl::EndElement()
 {
-    GetTransformer().GetDocHandler()->endElement( m_aElemQName );
+    GetTransformer().endFastElement( m_aElemQName );
 
     GetTransformer().SetClass( m_aOldClass );
 }
@@ -1267,13 +1267,13 @@ void XMLBodyTransformerContext_Impl::StartElement(
 
     m_aClassQName = GetTransformer().GetNamespaceMap().GetQNameByKey(
                         XML_NAMESPACE_OFFICE, aClass );
-    GetTransformer().GetDocHandler()->startElement( m_aClassQName,
+    GetTransformer().startFastElement( m_aClassQName,
                                                     xAttrList );
 }
 
 void XMLBodyTransformerContext_Impl::EndElement()
 {
-    GetTransformer().GetDocHandler()->endElement( m_aClassQName );
+    GetTransformer().endFastElement( m_aClassQName );
     XMLTransformerContext::EndElement();
 }
 
@@ -1483,12 +1483,12 @@ void XMLTableOOoTransformerContext_Impl::StartElement(
         }
     }
 
-    GetTransformer().GetDocHandler()->startElement( m_aElemQName, xAttrList );
+    GetTransformer().startFastElement( m_aElemQName, xAttrList );
 }
 
 void XMLTableOOoTransformerContext_Impl::EndElement()
 {
-    GetTransformer().GetDocHandler()->endElement( m_aElemQName );
+    GetTransformer().endFastElement( m_aElemQName );
 }
 
 XMLTransformerContext *OOo2OasisTransformer::CreateUserDefinedContext(
diff --git a/xmloff/source/transform/Oasis2OOo.cxx b/xmloff/source/transform/Oasis2OOo.cxx
index 257f199..e901264 100644
--- a/xmloff/source/transform/Oasis2OOo.cxx
+++ b/xmloff/source/transform/Oasis2OOo.cxx
@@ -1226,12 +1226,12 @@ void XMLTableTransformerContext_Impl::StartElement(
         }
     }
 
-    GetTransformer().GetDocHandler()->startElement( m_aElemQName, xAttrList );
+    GetTransformer().startFastElement( m_aElemQName, xAttrList );
 }
 
 void XMLTableTransformerContext_Impl::EndElement()
 {
-    GetTransformer().GetDocHandler()->endElement( m_aElemQName );
+    GetTransformer().endFastElement( m_aElemQName );
 }
 
 class XMLBodyOASISTransformerContext_Impl : public XMLTransformerContext
diff --git a/xmloff/source/transform/PersAttrListTContext.cxx b/xmloff/source/transform/PersAttrListTContext.cxx
index c604a09..f021af6 100644
--- a/xmloff/source/transform/PersAttrListTContext.cxx
+++ b/xmloff/source/transform/PersAttrListTContext.cxx
@@ -161,9 +161,9 @@ bool XMLPersAttrListTContext::IsPersistent() const
 
 void XMLPersAttrListTContext::Export()
 {
-    GetTransformer().GetDocHandler()->startElement( m_aElemQName, m_xAttrList );
+    GetTransformer().startFastElement( m_aElemQName, m_xAttrList );
     ExportContent();
-    GetTransformer().GetDocHandler()->endElement( m_aElemQName );
+    GetTransformer().endFastElement( m_aElemQName );
 }
 
 void XMLPersAttrListTContext::ExportContent()
diff --git a/xmloff/source/transform/ProcAddAttrTContext.cxx b/xmloff/source/transform/ProcAddAttrTContext.cxx
index 2adf278..821ccd9 100644
--- a/xmloff/source/transform/ProcAddAttrTContext.cxx
+++ b/xmloff/source/transform/ProcAddAttrTContext.cxx
@@ -60,7 +60,7 @@ void XMLProcAddAttrTransformerContext::StartElement(
         xAttrList = pMutableAttrList;
     }
     pMutableAttrList->AddAttribute( m_aAttrQName, m_aAttrValue );
-    GetTransformer().GetDocHandler()->startElement( GetElemQName(), xAttrList );
+    GetTransformer().startFastElement( GetElemQName(), xAttrList );
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/transform/ProcAttrTContext.cxx b/xmloff/source/transform/ProcAttrTContext.cxx
index 4f142b3..0af4e4c 100644
--- a/xmloff/source/transform/ProcAttrTContext.cxx
+++ b/xmloff/source/transform/ProcAttrTContext.cxx
@@ -56,12 +56,12 @@ void XMLProcAttrTransformerContext::StartElement(
 {
     Reference< XAttributeList > xAttrList( rAttrList );
     GetTransformer().ProcessAttrList( xAttrList, m_nActionMap, false );
-    GetTransformer().GetDocHandler()->startElement( m_aElemQName, xAttrList );
+    GetTransformer().startFastElement( m_aElemQName, xAttrList );
 }
 
 void XMLProcAttrTransformerContext::EndElement()
 {
-    GetTransformer().GetDocHandler()->endElement( m_aElemQName );
+    GetTransformer().endFastElement( m_aElemQName );
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/transform/RenameElemTContext.cxx b/xmloff/source/transform/RenameElemTContext.cxx
index 6816d66..81ea2da 100644
--- a/xmloff/source/transform/RenameElemTContext.cxx
+++ b/xmloff/source/transform/RenameElemTContext.cxx
@@ -69,12 +69,12 @@ void XMLRenameElemTransformerContext::StartElement(
         xAttrList = pMutableAttrList;
         pMutableAttrList->AddAttribute( m_aAttrQName, m_aAttrValue );
     }
-    GetTransformer().GetDocHandler()->startElement( m_aElemQName, xAttrList );
+    GetTransformer().startFastElement( m_aElemQName, xAttrList );
 }
 
 void XMLRenameElemTransformerContext::EndElement()
 {
-    GetTransformer().GetDocHandler()->endElement( m_aElemQName );
+    GetTransformer().endFastElement( m_aElemQName );
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/transform/StyleOASISTContext.cxx b/xmloff/source/transform/StyleOASISTContext.cxx
index 38a3d43..6018aa5 100644
--- a/xmloff/source/transform/StyleOASISTContext.cxx
+++ b/xmloff/source/transform/StyleOASISTContext.cxx
@@ -609,10 +609,9 @@ void XMLPropertiesTContext_Impl::StartElement(
 
 void XMLPropertiesTContext_Impl::Export()
 {
-    GetTransformer().GetDocHandler()->startElement( GetExportQName(),
-                                                    m_xAttrList );
+    GetTransformer().startFastElement( GetExportQName(), m_xAttrList );
     ExportContent();
-    GetTransformer().GetDocHandler()->endElement( GetExportQName() );
+    GetTransformer().endFastElement( GetExportQName() );
 }
 
 XMLPropType XMLPropertiesTContext_Impl::GetPropType( const OUString& rLocalName )
@@ -896,8 +895,7 @@ void XMLStyleOASISTContext::StartElement(
     if( m_bPersistent )
         XMLPersElemContentTContext::StartElement( xAttrList );
     else
-        GetTransformer().GetDocHandler()->startElement( GetExportQName(),
-                                                        xAttrList );
+        GetTransformer().startFastElement( GetExportQName(), xAttrList );
 }
 
 void XMLStyleOASISTContext::EndElement()
@@ -914,7 +912,7 @@ void XMLStyleOASISTContext::EndElement()
             m_xPropContext->Export();
             m_xPropContext = nullptr;
         }
-        GetTransformer().GetDocHandler()->endElement( GetExportQName() );
+        GetTransformer().endFastElement( GetExportQName() );
     }
 }
 
diff --git a/xmloff/source/transform/StyleOOoTContext.cxx b/xmloff/source/transform/StyleOOoTContext.cxx
index bf841ca..077e7b0 100644
--- a/xmloff/source/transform/StyleOOoTContext.cxx
+++ b/xmloff/source/transform/StyleOOoTContext.cxx
@@ -197,9 +197,9 @@ void XMLTypedPropertiesOOoTContext_Impl::Export()
 {
     if( m_xAttrList->getLength() || HasElementContent() )
     {
-        GetTransformer().GetDocHandler()->startElement( GetQName(), m_xAttrList );
+        GetTransformer().startFastElement( GetQName(), m_xAttrList );
         ExportContent();
-        GetTransformer().GetDocHandler()->endElement( GetQName() );
+        GetTransformer().endFastElement( GetQName() );
     }
 }
 
@@ -1254,8 +1254,7 @@ void XMLStyleOOoTContext::StartElement(
     if( m_bPersistent )
         XMLPersElemContentTContext::StartElement( xAttrList );
     else
-        GetTransformer().GetDocHandler()->startElement( GetExportQName(),
-                                                        xAttrList );
+        GetTransformer().startFastElement( GetExportQName(), xAttrList );
 }
 
 void XMLStyleOOoTContext::EndElement()
@@ -1263,7 +1262,7 @@ void XMLStyleOOoTContext::EndElement()
     if( m_bPersistent )
         XMLPersElemContentTContext::EndElement();
     else
-        GetTransformer().GetDocHandler()->endElement( GetExportQName() );
+        GetTransformer().endFastElement( GetExportQName() );
 }
 
 void XMLStyleOOoTContext::Characters( const OUString& )
diff --git a/xmloff/source/transform/TransformerBase.cxx b/xmloff/source/transform/TransformerBase.cxx
index f577072..08c4a21 100644
--- a/xmloff/source/transform/TransformerBase.cxx
+++ b/xmloff/source/transform/TransformerBase.cxx
@@ -40,6 +40,7 @@
 #include "TransformerTokenMap.hxx"
 
 #include "TransformerBase.hxx"
+#include <xmloff/xmlimp.hxx>
 
 using namespace ::osl;
 using namespace ::xmloff::token;
@@ -184,10 +185,13 @@ XMLTransformerActions *XMLTransformerBase::GetUserDefinedActions( sal_uInt16 )
 XMLTransformerBase::XMLTransformerBase( XMLTransformerActionInit *pInit,
                                     ::xmloff::token::XMLTokenEnum *pTKMapInit )
     throw () :
+    m_xTokenHandler( new FastTokenHandler() ),
     m_pNamespaceMap( new SvXMLNamespaceMap ),
     m_pReplaceNamespaceMap( new SvXMLNamespaceMap ),
     m_pElemActions( new XMLTransformerActions( pInit ) ),
-    m_pTokenMap( new XMLTransformerTokenMap( pTKMapInit ) )
+    m_pTokenMap( new XMLTransformerTokenMap( pTKMapInit ) ),
+    m_xFastAttributes( new sax_fastparser::FastAttributeList( m_xTokenHandler.get(),
+        dynamic_cast< sax_fastparser::FastTokenHandlerBase *>( m_xTokenHandler.get() ) ) )
 {
     GetNamespaceMap().Add( GetXMLToken(XML_NP_XLINK), GetXMLToken(XML_N_XLINK), XML_NAMESPACE_XLINK );
     GetNamespaceMap().Add( GetXMLToken(XML_NP_DC), GetXMLToken(XML_N_DC), XML_NAMESPACE_DC );
@@ -429,7 +433,12 @@ void SAL_CALL XMLTransformerBase::initialize( const Sequence< Any >& aArguments
 
         // document handler
         if( cppu::UnoType<XDocumentHandler>::get().isAssignableFrom( pAny->getValueType() ) )
+        {

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list