Calc/Implementation/Calc styles export
Basic concept of Styles
In the OpenDocument format, formatting properties, which influences the visual representation of objects, are stored in styles. Using styles to store formatting properties has advantages such as, format information is separated from document content, and styles enable consistent formatting and changing of formatting for objects subject to styles. Following picture is a sample of OpenDocument styles.xml file. This file is the main file for styles storage.
As styles.xml shows, both <style:default-style> and <style:style> in <office:styles> have a “style:name” attribute. In fact, styles and font face declarations are referenced by their style:name attribute[1]. A referenced style or font face declaration should be defined in the same file as the reference, or in styles.xml. Styles built in the stylist (can be used by click menu "Format"--"Styles and formatting") or ones that you create there, will have names like “Heading 1” or Custom Citation. Automatic styles <office:automatic-styles> will have names consisting of style-family abbreviation followed by a number; a style name such as T1 is the first automatic style for style:family="text"; P3 would be the third style for paragraphs, ta2 would be the second style for a table, ro4 would be the fourth style for a table row, etc(please refer content.xml for OpenDocument). The other attribute of interest is the optional parent-style-name, which you will find in styles that have been derived from other styles. <style:font-face> element represents a font face declaration which documents the properties of a font used in a document. OpenDocument font face declarations may have an unique name. This name can be used inside styles (as an attribute of <style:text-properties> element) as value of the style:font-name attribute to select a font face declaration. <style:style> element represents styles,and <style:default-style> element represents default styles. A default style specifies default formatting properties for a style family. These defaults are used if a formatting property is neither specified by an automatic nor a common style. Default styles exist for all style families that are represented by the <style:style> element specified by the style:family attribute. An OpenDocument document should contain the default styles of the style families for which are used in common or automatic styles in the document.<office:master-styles> <style:master-page> defines page styles which is in stylist.
File:Styles font face.xml .jpg
Attributes for elements defined by OpenDocument are divided between those used by structural elements[2] versus those used by <style:*-properties> elements. Attributes have default values defined by reference[2] standard, and when any element appears in a document instance without such an attribute, consumers should behave as if the attribute is present with the defined default value. <style:*-properties> elements is commonly used to aggregate attributes of one type for specific style. Formatting definitions are expressed as attributes on the <style:*-properties> elements or as child elements of these elements. From code perspective, these <office:styles> , <office:automatic-styles> etc elements in styles.xml is written by SvXMLExport::exportDoc( enum ::xmloff::token::XMLTokenEnum eClass ), when export ods, eClass is XML_SPREADSHEET. For example, ImplExportStyles() inside SvXMLExport::exportDoc() is for writing <office:styles> elements, _ExportFontDecls(); is for <office:font-face-decls>, and ImplExportAutoStyles() is for <office:automatic-styles>. Inside ImplExportStyles() , ScXMLExport::_ExportStyles will call exportDefaultStyle(), exportDataStyles(), exportStyleFamily() etc, in turn to export <style:default-style> <number:number-style>, <style:style> etc. ScXMLImportWrapper::ExportToComponent() is called with different parameters to export each file inside ods, such as styles.xml, content.xml.
Styles export sequence diagrams overview
<style:font-face> elements export is mainly in following sequence, <style: default style> elements is exported generally as following sequece,
Automatic styles export is mainly as below,
Main class for export, SvXMLExport and ScXMLExport
SvXMLExport is the main class for XML file export. It implements several UNO interfaces such as ::com::sun::star::document::Xfilter, which is used by service ImportFilter or ExportFilter to support loading/saving of documents in different formats, and ::com::sun::star::xml::sax::XDocumentHandler plus ::com::sun::star::xml::sax::XEntendedDocumentHandler, which is interfaces for calling SAX(an event-based sequential access parser API ). It also holds ::com::sun::star::frame::XModel to access document data model. And it use XMLFontAutoStylePool, SvXMLAutoStylePoolP to manage font declarations and automatic styles store plus export. Member UniReference< XMLPageExport > mxPageExport is used as child exporter, which export page styles; and UniReference< XMLShapeExport > mxShapeExport for exporting shape styles. It has function ImplExportStyles( ) for <office:styles> export, _ImplExportMasterStyles() for <style:master-styles> export, etc. ScXMLExport is derived from SvXMLExport and it holds specific SvXMLExportPropertyMapper for SC module, such as xCellStylesExportPropertySetMapper, xRowStylesExportPropertySetMapper. And ScColumnStyles, ScRowStyles etc for corresponding automatic styles export. It implements _ExportFontDecls(), _ExportStyles(), _ExportAutoStyles() etc to actually export styles. ScXMLExport will be constructed once writing a XML file such as styles.xml, content.xml.
class XMLOFF_DLLPUBLIC SvXMLExport { … SvXMLNamespaceMap *mpNamespaceMap; // the namepspace map SvXMLUnitConverter *mpUnitConv; // the unit converter UniReference< SvXMLAutoStylePoolP > mxAutoStylePool; UniReference< XMLFontAutoStylePool > mxFontAutoStylePool; SAL_DLLPRIVATE void ImplExportMeta(); // <office:meta> SAL_DLLPRIVATE void ImplExportSettings(); // <office:settings> SAL_DLLPRIVATE void ImplExportStyles( sal_Bool bUsed ); // <office:styles> SAL_DLLPRIVATE void ImplExportAutoStyles( sal_Bool bUsed );// <office:automatic-styles> SAL_DLLPRIVATE void ImplExportMasterStyles( sal_Bool bUsed ); // <office:master-styles> SAL_DLLPRIVATE void ImplExportContent(); // <office:body> // This method can be overloaded to export the font declarations // The default implementation will export the contents of the // XMLFontAutoStylePool if it has been created. virtual void _ExportFontDecls(); // This method should be overloaded to export the content of <style:styles>. // If bUsed is set, used styles should be exported only. // Overloaded Methods must call this method ! virtual void _ExportStyles( sal_Bool bUsed ) ; // methods for accessing the document handler and handling SAX errors void StartElement(sal_uInt16 nPrefix, enum ::xmloff::token::XMLTokenEnum eName, sal_Bool bIgnWSOutside ); … }
SvXMLElementExport is helper class to export an element, its constructors prints a start tag with the common attributes. For example, SvXMLElementExport aElement( GetExport(), XML_NAMESPACE_STYLE, XML_FONT_FACE, sal_True, sal_True ) could print tag <style:font-face style:name="Arial" svg:font-family="Arial" style:font-pitch="variable" /> . Constructor of SvXMLElementExport will indirectly call SvXMLExport::StartElement() to write XML. And the destructor ~SvXMLElementExport() prints an end tag. For different properties, process of writing XML is quite differently. Handling color will use XMLColorPropHdl for writing XML and string using XMLStringProHdl; meanwhile XMLPropertyHandler is abstract base-class for different XML-types. Derivations of XMLPropertyHandler knows how to compare, im/export a special XML-type. Some property types need SvXMLUnitConverter converts values from their internal represantation to the textual form used in xml and back.Most of the methods are static but the SvXMLUnitConverter can also store default units for both numerical and textual measures. For example, when XMLFontPitchPropHdl writing FontPitch property to XML, it use SvXMLUnitConverter::convertEnum() to convert enum FontPitch to textual form, by searching SvXMLEnumMapEntry aFontPitchMapping[] it will get mapped XMLTokenEnum and finally get corresponding text in xmltoken.cxx. Sample code is as below.
static SvXMLEnumMapEntry __READONLY_DATA aFontPitchMapping[] = { { XML_FIXED, PITCH_FIXED }, { XML_VARIABLE, PITCH_VARIABLE }, { XML_TOKEN_INVALID, 0 } }; sal_Bool XMLFontPitchPropHdl::exportXML( OUString& rStrExpValue, const uno::Any& rValue, const SvXMLUnitConverter& ) const { sal_Bool bRet = sal_False; sal_Int16 nPitch = sal_Int16(); OUStringBuffer aOut; FontPitch ePitch = PITCH_DONTKNOW; if( rValue >>= nPitch ) ePitch = (FontPitch)nPitch; if( PITCH_DONTKNOW != ePitch ) { bRet = SvXMLUnitConverter::convertEnum( aOut, ePitch, aFontPitchMapping, XML_FIXED ); rStrExpValue = aOut.makeStringAndClear(); } return bRet; }
XMLPropertySetMapper, SvXMLExportPropertyMapper, XMLPropertySetMapperEntry_Impl
XMLPropertySetMapper is helper class for XML im/export, it holds a pointer to a given array of XMLPropertySetMapperEntry_Impl, which is added by XMLPropertySetMapper::XMLPropertySetMapper(const XMLPropertyMapEntry* pEntries, const UniReference< XMLPropertyHandlerFactory >& rFactory ). XMLPropertyMapEntry* pEntries is usually passed from static array, such as XMLPropertyMapEntry aXMLScCellStylesProperties[], defined in xmlstyle.cxx, txtprmap.cxx etc. XMLPropertySetMapperEntry_Impl is basic element for export XML, it transforms XMLTokenEnum meXMLName inside XMLPropertyMapEntry to sXMLAttributeName, which will be written in XML, so it holds a Sequence of XML-names (for properties) for writing XML. XMLPropertySetMapperEntry_Impl also holds nContextId for context filter, for example, in text properties context, nContextId will only count id for text properties, it is defined intuitive in txtprmap.cxx, such as #define CTF_CHARHEIGHT (XML_TEXT_CTF_START + 1). sAPIPropertyName in XMLPropertySetMapperEntry_Impl is for UNO property-name. XMLPropertySetMapper provides several methods to access data from XMLPropertySetMapperEntry_Impl array, such as GetEntryXMLName( sal_Int32 nIndex ), GetEntryNameSpace( sal_Int32 nIndex ). Sample code is as below.
// xmloff\source\text\txtprmap.cxx XMLPropertyMapEntry aXMLParaPropMap[] , hundreds of entries. XMLPropertyMapEntry aXMLSectionPropMap XMLPropertyMapEntry aXMLTextPropMap[] XMLPropertyMapEntry aXMLShapePropMap[]
XMLPropertyMapEntry aXMLParaPropMap[] = { // RES_UNKNOWNATR_CONTAINER MP_E( "ParaUserDefinedAttributes", TEXT, XMLNS, XML_TYPE_ATTRIBUTE_CONTAINER | MID_FLAG_SPECIAL_ITEM, 0 ), // RES_LR_SPACE MP_E( "ParaLeftMargin", FO, MARGIN, XML_TYPE_MEASURE|MID_FLAG_MULTI_PROPE RTY, CTF_PARAMARGINALL ), ... } //ScXMLExport:: ScXMLExport() xCellStylesPropertySetMapper = new XMLPropertySetMapper((XMLPropertyMapEntry*)aXMLScCellStylesProperties, xScPropHdlFactory); xColumnStylesPropertySetMapper = new XMLPropertySetMapper((XMLPropertyMapEntry*)aXMLScColumnStylesProperties, xScPropHdlFactory); xCellStylesExportPropertySetMapper = new ScXMLCellExportPropertyMapper(xCellStylesPropertySetMapper); class XMLPropertySetMapper { ... /** Returns the flags of an entry */ sal_uInt32 GetEntryFlags( sal_Int32 nIndex ) const /** Returns the type of an entry */ sal_uInt32 GetEntryType( sal_Int32 nIndex, sal_Bool bWithFlags = sal_True ) const /** Returns the namespace-key of an entry */ sal_uInt16 GetEntryNameSpace( sal_Int32 nIndex ) const /** Returns the 'local' XML-name of the entry */ const ::rtl::OUString& GetEntryXMLName( sal_Int32 nIndex ) const /** Retrieves a PropertyHandler for that property wich placed at nIndex in the XMLPropertyMapEntry-array */ const XMLPropertyHandler* GetPropertyHandler( sal_Int32 nIndex ) const /** import/export This methods calls the respective im/export-method of the respective PropertyHandler. */ virtual sal_Bool exportXML( ::rtl::OUString& rStrExpValue, const XMLPropertyState& rProperty, const SvXMLUnitConverter& rUnitConverter ) const; ... }
For nType in property map entry (XMLPropertySetMapperEntry_Impl), 15th to 18th bits from right of it are for type index, mnIndex in XMLPropertyState correspond to this index, which will be mapped for query information when exportXML(). And 32nd to 14th bits from right of nType are used as flags, such as following definition in Xmltypes.hxx (lib\xmloff\inc\xmloff).
// Import and Export: The property in question must exist. No call to hasPropertyByName is required. #define MID_FLAG_MUST_EXIST 0x00400000 // Export only: When exporting defaults, export this property even if it is not set #define MID_FLAG_DEFAULT_ITEM_EXPORT 0x00200000
SvXMLExportPropertyMapper is the base class of ScXMLCellExportPropertyMapper, ScXMLColumnExportPropertyMapper etc. They hold XMLPropertySetMapper and knows how to compare with parameter XPropertySet and filter unwanted properties. SvXMLExportPropertyMapper has method Filter( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>) , which filter properties and only take all properties of the XPropertySet which are also found in the XMLPropertyMapEntry-array and which are not default or inherited. SvXMLExportPropertyMapper also has method FilterDefaults( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > rPropSet ) , which has quite similar process as Filter() except that it only takes properties that have the map flag MID_FLAG_DEFAULT_ITEM_EXPORT, and instead of the property's value, its defualt value is set for export. It holds mxNextMapper for stacked contextfilter(), which will be described afterwards. For writing XML, it has method exportXML(), which fills the SvXMLAttributeList& rAttrList with the items in std::vector< XMLPropertyState >& rProperties , and has handleSpecialItem() for every item that has the MID_FLAG_SPECIAL_ITEM_EXPORT flag.
For Filter() or FilterDefaults(), it will first exclude mapperEntries which has flag MID_FLAG_NO_PROPERTY_EXPORT out of properties intended export. Entries that is included in properties intended to export should furthmore meet followings, first, it has flags MID_FLAG_MUST_EXIST or input XPropertySet contains property type of this entry; second, ODFVersion is meeted; third, pass FillPropertyStateArray(aPropStateArray, xPropSet, maPropMapper, bDefault) and remain;(for FilterDefaults() , bDefault == true, and false for Filter() ); fourth, pass ContextFilter() and remain.
In FillPropertyStateArray(aPropStateArray, xPropSet, maPropMapper,bDefault), code will judge bDefault to export properties with defualt value or new value. Output parameter aPropStateArray will then filtered by stacked mxNextMapper->ContextFilter( ). Sample code is as below.
//SvXMLExportPropertyMapper::Filter( ), that is equal as _Filter(rPropSet, sal_False) for( sal_Int32 i=0; i < nProps; i++ ) { const OUString& rAPIName = maPropMapper->GetEntryAPIName( i ); const sal_Int32 nFlags = maPropMapper->GetEntryFlags( i ); if( (0 == (nFlags & MID_FLAG_NO_PROPERTY_EXPORT)) && ( (0 != (nFlags & MID_FLAG_MUST_EXIST)) || xInfo->hasPropertyByName( rAPIName ) ) ) { const SvtSaveOptions::ODFDefaultVersion nCurrentVersion( SvtSaveOptions().GetODFDefaultVersion() ); const SvtSaveOptions::ODFDefaultVersion nEarliestODFVersionForExport( maPropMapper->GetEarliestODFVersionForExport( i ) ); if( nCurrentVersion >= nEarliestODFVersionForExport || nCurrentVersion == SvtSaveOptions::ODFVER_UNKNOWN || nEarliestODFVersionForExport == SvtSaveOptions::ODFVER_UNKNOWN ) pFilterInfo->AddProperty(rAPIName, i); } }
ContextFilter() is application-specific filter, just as XMLPageExportPropertyMapper, ScXMLCellExportPropertyMapper, XMLTextExportPropertySetMapper has different implementation, and by default it do nothing. Take XMLTextExportPropertySetMapper for exmaple, ContextFilter() is as follows,
void XMLTextExportPropertySetMapper::ContextFilter( ::std::vector< XMLPropertyState >& rProperties, Reference< XPropertySet > rPropSet ) const void XMLTextExportPropertySetMapper::ContextFontFilter(XMLPropertyState *pFontNameState, XMLPropertyState *pFontFamilyNameState, XMLPropertyState *pFontStyleNameState, XMLPropertyState *pFontFamilyState, XMLPropertyState *pFontPitchState, XMLPropertyState *pFontCharsetState ) const { ... OUString sName( ((SvXMLExport&)GetExport()).GetFontAutoStylePool()->Find( sFamilyName, sStyleName, nFamily, nPitch, eEnc ) ); if( sName.getLength() ) { pFontNameState->maValue <<= sName; if( pFontFamilyNameState ) pFontFamilyNameState->mnIndex = -1; if( pFontStyleNameState ) pFontStyleNameState->mnIndex = -1; if( pFontFamilyState ) pFontFamilyState->mnIndex = -1; if( pFontPitchState ) pFontPitchState->mnIndex = -1; if( pFontCharsetState ) pFontCharsetState->mnIndex = -1; } ... }
When Find( sFamilyName, sStyleName, nFamily, nPitch, eEnc ) got valid sName, then text specific properties pFontFamilyNameState, pFontStyleNameState will be filtered and not exported, meanwhile pFontNameState is enough to determine needed element attributes.
After above filter process, SvXMLExportPropertyMapper::exportXML() will use the filter result std::vector< XMLPropertyState >& rProperties to write XML. In outer iteration of exportXML( ), code will iterate each type of 14 property types ( PAGE, SECTION, TEXT, GRAPHIC,CHART, COLUMN etc.) to export each type in turn ( write all of one type's property value string in XML files and then the next type, in order to show different type of properties in different lines inside XML tags, just like below picture).
The XML parts in this picture is write by ScXMLExport::_ExportStyles, aStylesExp.exportDefaultStyle(xProperties, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM (XML_STYLE_FAMILY_TABLE_CELL_STYLES_NAME)), xCellStylesExportPropertySetMapper). For the first type of properties, _exportXML( ) will iterate each element of std::vector< XMLPropertyState >& rProperties, and set rPropTypeFlags which marks property-map entries containing which property types. For the second type and so on, if judge rPropTypeFlags don't contain the type, it will not call _exportXML( ) so as to reduce time cost. For each type, code will iterate every property in rProperties, if property index is among nPropMapStartIdx and nPropMapEndIdx of XMLPropertySetMapper and property type matchs, it will be exported. In _exportXML( ), if rPropTypeFlags match MID_FLAG_ELEMENT_ITEM_EXPORT, it will be stored in SvUShorts* pIndexArray, and finally call SvXMLExportPropertyMapper::exportElementItems() to export.
In above exportXML(), each property in rProperties is queried probably by several times, so the performance improvemence could be considered. There are also some styles which don't call SvXMLExportPropertyMapper::exportXML(). When XMLPageExport export automatic-styles, code will call ScXMLAutoStylePoolP::exportStyleAttributes() to export attributes of each style type, for example, style:name="ta1" style:family="table", and style:master-page-name, which is in XMLPropertyMapEntry aXMLScTableStylesProperties[]. style:master-page-name is not like two other entries in aXMLScTableStylesProperties [], which is exported by SvXMLExportPropertyMapper::exportXML() and put into child elements.
SvXMLAutoStylePoolP, ScXMLAutoStylePoolP, XMLFamilyDataList_Impl, SvXMLAutoStylePoolParentP_Impl
SvXMLAutoStylePoolP is the main class for automatic styles export. ScXMLAutoStylePoolP is derived from SvXMLAutoStylePoolP and could export SC specific style attributes.
SvXMLAutoStylePoolP holds pointer of SvXMLAutoStylePoolP_Impl, which is implemention class for function such as Add( ), AddFamily() and exportXML(). SvXMLAutoStylePoolP_Impl also holds XMLFamilyDataList_Impl aFamilyList. When class ScXMLExport is constructed, AddFamily( ) is called to add various type of XMLFamilyData_Impl, such as table-cell, table-column etc., to XMLFamilyDataList_Impl. XMLFamilyData_Impl is data structure for each type of style family, and it stores mnFamily as family ID, maStrPrefix as family prefix (such as ce, co, ta), and mnCount as count of SvXMLAutoStylePoolPropertiesP_Impl. mnCount is copied to mnPos of SvXMLAutoStylePoolPropertiesP_Impl when add properties. SvXMLAutoStylePoolP_Impl:: Add( ) is used to add a array of XMLPropertyState to maPropertiesList of corresponding SvXMLAutoStylePoolParentP_Impl if not added yet.
SvXMLAutoStylePoolParentP_Impl is parents of AutoStylePool, and XMLFamilyData use several SvXMLAutoStylePoolParentP_Impl for storing styles in its maPropertiesList. SvXMLAutoStylePoolParentP_Impl holds msParent as parent name, such as "Default" in xml tag style:parent-style-name="Default". Sample code is as below.
// Parents of AutoStylePool's class SvXMLAutoStylePoolParentP_Impl { ::rtl::OUString msParent; SvXMLAutoStylePoolPropertiesPList_Impl maPropertiesList; ... } class XMLFamilyData_Impl { public: SvXMLAutoStylePoolCache_Impl *pCache; sal_uInt32 mnFamily; ::rtl::OUString maStrFamilyName;//such as table-column UniReference < SvXMLExportPropertyMapper > mxMapper; SvXMLAutoStylePoolParentsP_Impl* mpParentList;// sorted list of SvXMLAutoStylePoolParentP_Impl SvXMLAutoStylePoolNamesP_Impl* mpNameList; sal_uInt32 mnCount;//count of SvXMLAutoStylePoolPropertiesP_Impl sal_uInt32 mnName; ::rtl::OUString maStrPrefix; sal_Bool bAsFamily; ... } class SvXMLAutoStylePoolP_Impl { SvXMLExport& rExport; XMLFamilyDataList_Impl maFamilyList; ... }
For properties filter process of ScXMLExport :: _ExportAutoStyles( ), code will call xTableStylesExportPropertySetMapper to filter xTableProperties and add output xPropStates to ScXMLAutoStylePoolP, the same is using xColumnStylesExportPropertySetMapper to filter xColumnProperties. In xTableProperties filter process, it will seek whether XMLFamilyDataList_Impl of this ScXMLAutoStylePoolP has family data of table type, if exist, it will furthermore seek SvXMLAutoStylePoolParentsP_Impl of this family data. If searched pool parent is not in SvXMLAutoStylePoolParentsP_Impl, it will create a new pool parent, and insert into SvXMLAutoStylePoolParentsP_Impl. Using the new pool parent, it add filtered properties, and update corresponding XMLFamilyData_Impl. The properties is finally put in SvXMLAutoStylePoolPropertiesP_Impl, and msName, such as ce1, co1 etc., is created from pFamilyData->maStrPrefix and pFamilyData->mnName.
When SvXMLAutoStylePoolP::exportXML( sal_Int32 nFamily, const uno::Reference< ::com::sun::star::xml::sax::XDocumentHandler > &, const SvXMLUnitConverter&, const SvXMLNamespaceMap&), it will seek input type of family data in maFamilyList, and if exist, it will iterate all SvXMLAutoStylePoolParentP_Impl in found family data and all properties in SvXMLAutoStylePoolPropertiesPList_Impl of each SvXMLAutoStylePoolParentP_Impl, and then save these properties in array of SvXMLAutoStylePoolPExport_Impl, which will be exported to XML by pFamily->mxMapper->exportXML(). Sample code is as below.
struct SvXMLAutoStylePoolPExport_Impl { const ::rtl::OUString *mpParent; const SvXMLAutoStylePoolPropertiesP_Impl *mpProperties; }; class SvXMLAutoStylePoolPropertiesP_Impl { ::rtl::OUString msName;//such asco1, stylename ::std::vector< XMLPropertyState > maProperties; sal_uInt32 mnPos;// pFamilyData->mnCount ... }
=XMLToken
In styles.xml, we usually see attributes like style:font-name="Arial", this attribute is constructed by SvXMLExport::AddAttribute() and then added to SvXMLAttributeList mpAttrList and construct SvXMLTagAttribute_Impl, which is finally written into styles.xml by SAXWriter. Sample code is as below.
void SvXMLExport::AddAttribute( sal_uInt16 nPrefixKey, enum XMLTokenEnum eName, const OUString& rValue ) { mpAttrList->AddAttribute( mpNamespaceMap->GetQNameByKey( nPrefixKey, GetXMLToken(eName) ), rValue ); }
void SvXMLAttributeList::AddAttribute( const OUString &sName , const OUString &sValue ) { m_pImpl->vecAttribute.push_back( SvXMLTagAttribute_Impl( sName , sValue ) ); }
For style:font-name="Arial", input parameters of SvXMLExport::AddAttribute() is, nPrefixKey:1, eName: XML_FONT_NAME, rValue:Arial. GetXMLToken(eName) get XML string for eName inside struct XMLTokenEntry aTokenList in xmltoken.cxx(lib\xmloff\source\core).When export style family, code get string for family name token in Families.hxx (xmloff\inc\xmloff). For GetQNameByKey(), we have to know how SvXMLNamespaceMap add entries before. In xmlnmspe.hxx, XML_NAMESPACE( STYLE, 1U ) defines XML_NAMESPACE_STYLE. When call xServiceFactory->createInstanceWithArguments( sComponentName , aArgs ), it will construct SvXMLExport, and _initCtor() inside xmlexp.cxx, mpNamespaceMap->Add( GetXMLToken(XML_NP_STYLE), GetXMLToken(XML_N_STYLE), XML_NAMESPACE_STYLE ) add NameSpaceEntry holding full namespace name and prefix for key XML_NAMESPACE_STYLE.
Fnd NameSpaceEntry entry in aNameMap of SvXMLNamespaceMap by nKey, then get prefix "style" from the entry and append input parameter rLocalName, which get "style:font-name". After that, QNameCache will cache these infomation,and when next time call GetQNameByKey() with same parameters, code could find entry in QNameCache by key QNamePair ( nKey, &rLocalName ), the second element of the found entry is "style:font-name".
class NameSpaceEntry : public cppu::OWeakObject { public: // sName refers to the full namespace name ::rtl::OUString sName; // sPrefix is the prefix used to declare a given item to be from a given namespace ::rtl::OUString sPrefix; // nKey is the unique identifier of a namespace sal_uInt16 nKey; };