LibreOffice Module xmloff (master) 1
xmlexppr.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <memory>
21#include <optional>
22#include <string_view>
23#include <com/sun/star/container/XNameContainer.hpp>
24#include <com/sun/star/xml/AttributeData.hpp>
25#include <com/sun/star/beans/XPropertySet.hpp>
26#include <com/sun/star/beans/XPropertyState.hpp>
27#include <com/sun/star/beans/XMultiPropertySet.hpp>
28#include <com/sun/star/beans/XTolerantMultiPropertySet.hpp>
29#include <com/sun/star/beans/TolerantPropertySetResultType.hpp>
30#include <rtl/ustrbuf.hxx>
33#include <osl/diagnose.h>
34#include <list>
35#include <map>
37
38#include <utility>
39#include <xmloff/xmlexppr.hxx>
40#include <xmloff/xmltoken.hxx>
43#include <xmloff/xmlexp.hxx>
44#include <xmloff/xmlprmap.hxx>
45#include <xmloff/maptype.hxx>
46#include <xmloff/xmltypes.hxx>
47#include <xmloff/xmlprhdl.hxx>
48
49using namespace ::std;
50using namespace ::com::sun::star;
51using namespace ::com::sun::star::beans;
52using namespace ::com::sun::star::uno;
53using namespace ::com::sun::star::lang;
54using namespace ::xmloff::token;
55
56#define GET_PROP_TYPE( f ) static_cast<sal_uInt16>((f & XML_TYPE_PROP_MASK) >> XML_TYPE_PROP_SHIFT)
57#define ENTRY(t) { GET_PROP_TYPE(XML_TYPE_PROP_##t), XML_##t##_PROPERTIES }
58
59namespace {
60
61struct XMLPropTokens_Impl
62{
63 sal_uInt16 nType;
65};
66
67const sal_uInt16 MAX_PROP_TYPES =
70
71XMLPropTokens_Impl const aPropTokens[MAX_PROP_TYPES] =
72{
73 ENTRY(CHART),
75 ENTRY(TABLE),
79 ENTRY(LIST_LEVEL),
81 ENTRY(TEXT),
83 ENTRY(PAGE_LAYOUT),
85 ENTRY(RUBY),
87};
88
89// public methods
90
91// Take all properties of the XPropertySet which are also found in the
92// XMLPropertyMapEntry-array and which are not set to their default-value,
93// if a state is available.
94// After that I call the method 'ContextFilter'.
95
96struct ComparePropertyState
97{
98 bool operator()(XMLPropertyState const& lhs, XMLPropertyState const& rhs)
99 {
100 return lhs.mnIndex < rhs.mnIndex;
101 }
102};
103class XMLPropertyStates_Impl
104{
106public:
107 XMLPropertyStates_Impl();
108 void AddPropertyState(const XMLPropertyState& rPropState);
109 void FillPropertyStateVector(std::vector<XMLPropertyState>& rVector);
110};
111
112XMLPropertyStates_Impl::XMLPropertyStates_Impl()
113{
114}
115
116void XMLPropertyStates_Impl::AddPropertyState(
117 const XMLPropertyState& rPropState)
118{
119 aPropStates.insert(rPropState);
120}
121
122void XMLPropertyStates_Impl::FillPropertyStateVector(
123 std::vector<XMLPropertyState>& rVector)
124{
125 rVector.insert( rVector.begin(), aPropStates.begin(), aPropStates.end() );
126}
127
128class FilterPropertyInfo_Impl
129{
130 OUString msApiName;
131 std::vector<sal_uInt32> maIndexes;
132
133public:
134
135 FilterPropertyInfo_Impl( OUString aApiName,
136 const sal_uInt32 nIndex);
137
138 const OUString& GetApiName() const { return msApiName; }
139 std::vector<sal_uInt32>& GetIndexes() { return maIndexes; }
140
141 // for sort
142 bool operator< ( const FilterPropertyInfo_Impl& rArg ) const
143 {
144 return (GetApiName() < rArg.GetApiName());
145 }
146};
147
148FilterPropertyInfo_Impl::FilterPropertyInfo_Impl(
149 OUString aApiName,
150 const sal_uInt32 nIndex ) :
151 msApiName(std::move( aApiName ))
152{
153 maIndexes.push_back(nIndex);
154}
155
156typedef std::list<FilterPropertyInfo_Impl> FilterPropertyInfoList_Impl;
157
158class FilterPropertiesInfo_Impl
159{
160 FilterPropertyInfoList_Impl aPropInfos;
161
162 std::optional<Sequence<OUString>> mxApiNames;
163
164public:
165 FilterPropertiesInfo_Impl();
166
167 void AddProperty(const OUString& rApiName, const sal_uInt32 nIndex);
168 const uno::Sequence<OUString>& GetApiNames();
169 void FillPropertyStateArray(
170 vector< XMLPropertyState >& rPropStates,
171 const Reference< XPropertySet >& xPropSet,
172 const rtl::Reference< XMLPropertySetMapper >& maPropMapper,
173 const bool bDefault,
174 const uno::Sequence<OUString>* pOnlyTheseProps);
175 sal_uInt32 GetPropertyCount() const { return aPropInfos.size(); }
176};
177
178FilterPropertiesInfo_Impl::FilterPropertiesInfo_Impl()
179{
180}
181
182void FilterPropertiesInfo_Impl::AddProperty(
183 const OUString& rApiName, const sal_uInt32 nIndex)
184{
185 aPropInfos.emplace_back(rApiName, nIndex);
186
187 OSL_ENSURE( !mxApiNames, "performance warning: API names already retrieved" );
188 mxApiNames.reset();
189}
190
191const uno::Sequence<OUString>& FilterPropertiesInfo_Impl::GetApiNames()
192{
193 if( !mxApiNames )
194 {
195 // we have to do three things:
196 // 1) sort API names,
197 // 2) merge duplicates,
198 // 3) construct sequence
199
200 // sort names
201 aPropInfos.sort();
202
203 // merge duplicates
204 if ( aPropInfos.size() > 1 )
205 {
206 FilterPropertyInfoList_Impl::iterator aOld = aPropInfos.begin();
207 FilterPropertyInfoList_Impl::iterator aEnd = aPropInfos.end();
208 FilterPropertyInfoList_Impl::iterator aCurrent = aOld;
209 ++aCurrent;
210
211 while ( aCurrent != aEnd )
212 {
213 // equal to next element?
214 if ( aOld->GetApiName() == aCurrent->GetApiName() )
215 {
216 // if equal: merge index lists
217 std::vector<sal_uInt32> aMerged;
218 std::merge(aOld->GetIndexes().begin(), aOld->GetIndexes().end(),
219 aCurrent->GetIndexes().begin(), aCurrent->GetIndexes().end(),
220 std::back_inserter(aMerged));
221 aOld->GetIndexes() = std::move(aMerged);
222 aCurrent->GetIndexes().clear();
223 // erase element, and continue with next
224 aCurrent = aPropInfos.erase( aCurrent );
225 }
226 else
227 {
228 // remember old element and continue with next
229 aOld = aCurrent;
230 ++aCurrent;
231 }
232 }
233 }
234
235 // construct sequence
236 mxApiNames.emplace( aPropInfos.size() );
237 OUString *pNames = mxApiNames->getArray();
238
239 for (auto const& propInfo : aPropInfos)
240 {
241 *pNames = propInfo.GetApiName();
242 ++pNames;
243 }
244 }
245
246 return *mxApiNames;
247}
248
249void FilterPropertiesInfo_Impl::FillPropertyStateArray(
250 vector< XMLPropertyState >& rPropStates,
251 const Reference< XPropertySet >& rPropSet,
253 const bool bDefault,
254 const uno::Sequence<OUString>* pOnlyTheseProps )
255{
256
257 XMLPropertyStates_Impl aPropStates;
258
259 const uno::Sequence<OUString>* pApiNames = pOnlyTheseProps;
260 if (!pApiNames)
261 pApiNames = &GetApiNames();
262
263 Reference < XTolerantMultiPropertySet > xTolPropSet( rPropSet, UNO_QUERY );
264 if (xTolPropSet.is())
265 {
266 if (!bDefault)
267 {
268 Sequence < beans::GetDirectPropertyTolerantResult > aResults(xTolPropSet->getDirectPropertyValuesTolerant(*pApiNames));
269 sal_Int32 nResultCount(aResults.getLength());
270 if (nResultCount > 0)
271 {
272 const beans::GetDirectPropertyTolerantResult *pResults = aResults.getConstArray();
273 FilterPropertyInfoList_Impl::iterator aPropIter(aPropInfos.begin());
274 XMLPropertyState aNewProperty( -1 );
275 while (nResultCount > 0 && aPropIter != aPropInfos.end())
276 {
277 if (pResults->Name == aPropIter->GetApiName())
278 {
279 aNewProperty.mnIndex = -1;
280 aNewProperty.maValue = pResults->Value;
281
282 for (auto const& index : aPropIter->GetIndexes())
283 {
284 aNewProperty.mnIndex = index;
285 aPropStates.AddPropertyState( aNewProperty );
286 }
287 ++pResults;
288 --nResultCount;
289 }
290 ++aPropIter;
291 }
292 }
293 }
294 else
295 {
296 const Sequence < beans::GetPropertyTolerantResult > aResults(xTolPropSet->getPropertyValuesTolerant(*pApiNames));
297 OSL_ENSURE( pApiNames->getLength() == aResults.getLength(), "wrong implemented XTolerantMultiPropertySet" );
298 FilterPropertyInfoList_Impl::iterator aPropIter(aPropInfos.begin());
299 XMLPropertyState aNewProperty( -1 );
300 OSL_ENSURE( aPropInfos.size() == static_cast<sal_uInt32>(aResults.getLength()), "wrong implemented XTolerantMultiPropertySet??" );
301 for( const auto& rResult : aResults )
302 {
303 if ((rResult.Result == beans::TolerantPropertySetResultType::SUCCESS) &&
304 ((rResult.State == PropertyState_DIRECT_VALUE) || (rResult.State == PropertyState_DEFAULT_VALUE)))
305 {
306 aNewProperty.mnIndex = -1;
307 aNewProperty.maValue = rResult.Value;
308
309 for (auto const& index : aPropIter->GetIndexes())
310 {
311 aNewProperty.mnIndex = index;
312 aPropStates.AddPropertyState( aNewProperty );
313 }
314 }
315 ++aPropIter;
316 }
317 }
318 }
319 else
320 {
321 Sequence < PropertyState > aStates;
322 const PropertyState *pStates = nullptr;
323 Reference< XPropertyState > xPropState( rPropSet, UNO_QUERY );
324 if( xPropState.is() )
325 {
326 aStates = xPropState->getPropertyStates( *pApiNames );
327 pStates = aStates.getConstArray();
328 }
329
330 Reference < XMultiPropertySet > xMultiPropSet( rPropSet, UNO_QUERY );
331 if( xMultiPropSet.is() && !bDefault )
332 {
333 Sequence < Any > aValues;
334 if( pStates )
335 {
336 // step 1: get value count
337 sal_uInt32 nValueCount = 0;
338
339 for (size_t i = 0; i < aPropInfos.size(); ++i, ++pStates)
340 {
341 if( *pStates == PropertyState_DIRECT_VALUE )
342 nValueCount++;
343 }
344
345 if( nValueCount )
346 {
347 // step 2: collect property names
348 Sequence < OUString > aAPINames( nValueCount );
349 OUString *pAPINames = aAPINames.getArray();
350
351 ::std::vector< FilterPropertyInfoList_Impl::iterator > aPropIters;
352 aPropIters.reserve( nValueCount );
353
354 FilterPropertyInfoList_Impl::iterator aItr = aPropInfos.begin();
355 OSL_ENSURE(aItr != aPropInfos.end(),"Invalid iterator!");
356
357 pStates = aStates.getConstArray();
358 sal_uInt32 i = 0;
359 while( i < nValueCount )
360 {
361 if( *pStates == PropertyState_DIRECT_VALUE )
362 {
363 *pAPINames++ = aItr->GetApiName();
364 aPropIters.push_back( aItr );
365 ++i;
366 }
367 ++aItr;
368 ++pStates;
369 }
370
371 aValues = xMultiPropSet->getPropertyValues( aAPINames );
372 const Any *pValues = aValues.getConstArray();
373
374 ::std::vector< FilterPropertyInfoList_Impl::iterator >::const_iterator
375 pPropIter = aPropIters.begin();
376
377 XMLPropertyState aNewProperty( -1 );
378 for( i = 0; i < nValueCount; ++i )
379 {
380 aNewProperty.mnIndex = -1;
381 aNewProperty.maValue = *pValues;
382
383 for (auto const& index : (*pPropIter)->GetIndexes())
384 {
385 aNewProperty.mnIndex = index;
386 aPropStates.AddPropertyState( aNewProperty );
387 }
388
389 ++pPropIter;
390 ++pValues;
391 }
392 }
393 }
394 else
395 {
396 aValues = xMultiPropSet->getPropertyValues( *pApiNames );
397 const Any *pValues = aValues.getConstArray();
398
399 FilterPropertyInfoList_Impl::iterator aItr = aPropInfos.begin();
400 for (size_t i = 0; i < aPropInfos.size(); ++i)
401 {
402 // The value is stored in the PropertySet itself, add to list.
403 XMLPropertyState aNewProperty( -1 );
404 aNewProperty.maValue = *pValues;
405 ++pValues;
406 for (auto const& index : aItr->GetIndexes())
407 {
408 aNewProperty.mnIndex = index;
409 aPropStates.AddPropertyState( aNewProperty );
410 }
411 ++aItr;
412 }
413 }
414 }
415 else
416 {
417 FilterPropertyInfoList_Impl::iterator aItr = aPropInfos.begin();
418 for (size_t i = 0; i < aPropInfos.size(); ++i)
419 {
420 bool bDirectValue =
421 !pStates || *pStates == PropertyState_DIRECT_VALUE;
422 if( bDirectValue || bDefault )
423 {
424 // The value is stored in the PropertySet itself, add to list.
425 bool bGotValue = false;
426 XMLPropertyState aNewProperty( -1 );
427 for (auto const& index : aItr->GetIndexes())
428 {
429 if( bDirectValue ||
430 (rPropMapper->GetEntryFlags(index) &
432 {
433 try
434 {
435 if( !bGotValue )
436 {
437 aNewProperty.maValue =
438 rPropSet->getPropertyValue( aItr->GetApiName() );
439 bGotValue = true;
440 }
441 aNewProperty.mnIndex = index;
442 aPropStates.AddPropertyState( aNewProperty );
443 }
444 catch( UnknownPropertyException& )
445 {
446 // might be a problem of getImplementationId
447 OSL_ENSURE( false, "unknown property in getPropertyValue" );
448 }
449
450 }
451 }
452 }
453
454 ++aItr;
455 if( pStates )
456 ++pStates;
457 }
458 }
459 }
460 aPropStates.FillPropertyStateVector(rPropStates);
461}
462
463}
464
466{
467 typedef std::map<css::uno::Reference<css::beans::XPropertySetInfo>, std::unique_ptr<FilterPropertiesInfo_Impl>> CacheType;
469
472
473 OUString maStyleName;
474};
475
476// ctor/dtor , class SvXMLExportPropertyMapper
477
480 mpImpl(new Impl)
481{
482 mpImpl->mxPropMapper = rMapper;
483}
484
486{
487}
488
491{
492 // add map entries from rMapper to current map
493 mpImpl->mxPropMapper->AddMapperEntry( rMapper->getPropertySetMapper() );
494 // rMapper uses the same map as 'this'
495 rMapper->mpImpl->mxPropMapper = mpImpl->mxPropMapper;
496
497 // set rMapper as last mapper in current chain
499 if( xNext.is())
500 {
501 while (xNext->mpImpl->mxNextMapper.is())
502 xNext = xNext->mpImpl->mxNextMapper;
503 xNext->mpImpl->mxNextMapper = rMapper;
504 }
505 else
506 mpImpl->mxNextMapper = rMapper;
507
508 // if rMapper was already chained, correct
509 // map pointer of successors
510 xNext = rMapper;
511
512 while (xNext->mpImpl->mxNextMapper.is())
513 {
514 xNext = xNext->mpImpl->mxNextMapper;
515 xNext->mpImpl->mxPropMapper = mpImpl->mxPropMapper;
516 }
517}
518
519std::vector<XMLPropertyState> SvXMLExportPropertyMapper::Filter(
520 SvXMLExport const& rExport,
521 const uno::Reference<beans::XPropertySet>& rPropSet,
522 bool bEnableFoFontFamily,
523 const uno::Sequence<OUString>* pOnlyTheseProps ) const
524{
525 return Filter_(rExport, rPropSet, false, bEnableFoFontFamily, pOnlyTheseProps);
526}
527
528std::vector<XMLPropertyState> SvXMLExportPropertyMapper::FilterDefaults(
529 SvXMLExport const& rExport,
530 const uno::Reference<beans::XPropertySet>& rPropSet ) const
531{
532 return Filter_(rExport, rPropSet, true, false/*bEnableFoFontFamily*/, nullptr);
533}
534
535vector<XMLPropertyState> SvXMLExportPropertyMapper::Filter_(
536 SvXMLExport const& rExport,
537 const Reference<XPropertySet>& xPropSet, bool bDefault, bool bEnableFoFontFamily,
538 const uno::Sequence<OUString>* pOnlyTheseProps ) const
539{
540 vector< XMLPropertyState > aPropStateArray;
541
542 // Retrieve XPropertySetInfo and XPropertyState
543 Reference< XPropertySetInfo > xInfo( xPropSet->getPropertySetInfo() );
544 if( !xInfo.is() )
545 return aPropStateArray;
546
547 sal_Int32 nProps = mpImpl->mxPropMapper->GetEntryCount();
548
549 FilterPropertiesInfo_Impl *pFilterInfo = nullptr;
550
551 Impl::CacheType::iterator aIter = mpImpl->maCache.find(xInfo);
552 if (aIter != mpImpl->maCache.end())
553 pFilterInfo = (*aIter).second.get();
554
555 bool bDelInfo = false;
556 if( !pFilterInfo )
557 {
559 const SvtSaveOptions::ODFSaneDefaultVersion nCurrentVersion(rExport.getSaneDefaultVersion());
560 pFilterInfo = new FilterPropertiesInfo_Impl;
561 for( sal_Int32 i=0; i < nProps; i++ )
562 {
563 // Are we allowed to ask for the property? (MID_FLAG_NO_PROP..)
564 // Does the PropertySet contain name of mpEntries-array ?
565 const OUString& rAPIName = mpImpl->mxPropMapper->GetEntryAPIName( i );
566 const sal_Int32 nFlags = mpImpl->mxPropMapper->GetEntryFlags( i );
567 if( (0 == (nFlags & MID_FLAG_NO_PROPERTY_EXPORT)) &&
568 ( (0 != (nFlags & MID_FLAG_MUST_EXIST)) ||
569 xInfo->hasPropertyByName( rAPIName ) ) )
570 {
571 const SvtSaveOptions::ODFSaneDefaultVersion nEarliestODFVersionForExport(
572 mpImpl->mxPropMapper->GetEarliestODFVersionForExport(i));
573 // note: only standard ODF versions are allowed here,
574 // only exception is the unknown future
575 assert((nEarliestODFVersionForExport & SvtSaveOptions::ODFSVER_EXTENDED) == 0
576 || nEarliestODFVersionForExport == SvtSaveOptions::ODFSVER_FUTURE_EXTENDED);
579 static sal_uInt16 s_OdfNs[] = {
605 };
606 static bool s_Assert(false);
607 if (!s_Assert)
608 {
609 assert(std::is_sorted(std::begin(s_OdfNs), std::end(s_OdfNs)));
610 s_Assert = true;
611 }
612 //static_assert(std::is_sorted(std::begin(s_OdfNs), std::end(s_OdfNs)));
613 auto const ns(mpImpl->mxPropMapper->GetEntryNameSpace(i));
614 auto const iter(std::lower_bound(std::begin(s_OdfNs), std::end(s_OdfNs),
615 ns));
616 bool const isExtension(iter == std::end(s_OdfNs) || *iter != ns
617 // FIXME: very special hack to suppress style:hyperlink
619 && mpImpl->mxPropMapper->GetEntryXMLName(i) == GetXMLToken(XML_HYPERLINK)));
620 if (isExtension
621 ? ((nCurrentVersion & SvtSaveOptions::ODFSVER_EXTENDED)
622 // if it's in standard ODF, don't export extension
623 && (nCurrentVersion < nEarliestODFVersionForExport))
624 : (nEarliestODFVersionForExport <= nCurrentVersion))
625 {
626 pFilterInfo->AddProperty(rAPIName, i);
627 }
628 }
629 }
630
631 // Check whether the property set info is destroyed if it is assigned to
632 // a weak reference only; If it is destroyed, then every instance of
633 // getPropertySetInfo returns a new object; such property set infos must
634 // not be cached:
635 WeakReference < XPropertySetInfo > xWeakInfo( xInfo );
636 xInfo.clear();
637 xInfo = xWeakInfo;
638 if( xInfo.is() )
639 {
640 mpImpl->maCache.emplace(xInfo, std::unique_ptr<FilterPropertiesInfo_Impl>(pFilterInfo));
641 }
642 else
643 bDelInfo = true;
644 }
645
646 if( pFilterInfo->GetPropertyCount() )
647 {
648 try
649 {
650 pFilterInfo->FillPropertyStateArray(
651 aPropStateArray, xPropSet, mpImpl->mxPropMapper, bDefault, pOnlyTheseProps);
652 }
653 catch( UnknownPropertyException& )
654 {
655 // might be a problem of getImplementationId
656 OSL_ENSURE( false, "unknown property in getPropertyStates" );
657 }
658 }
659
660 // Call context-filter
661 if( !aPropStateArray.empty() )
662 ContextFilter(bEnableFoFontFamily, aPropStateArray, xPropSet);
663
664 // Have to do if we change from a vector to a list or something like that
665
666 if( bDelInfo )
667 delete pFilterInfo;
668
669 return aPropStateArray;
670}
671
673 bool bEnableFoFontFamily,
674 vector< XMLPropertyState >& rProperties,
675 const Reference< XPropertySet >& rPropSet ) const
676{
677 // Derived class could implement this.
678 if (mpImpl->mxNextMapper.is())
679 mpImpl->mxNextMapper->ContextFilter(bEnableFoFontFamily, rProperties, rPropSet);
680}
681
682// Compares two Sequences of XMLPropertyState:
683// 1.Number of elements equal ?
684// 2.Index of each element equal ? (So I know whether the propertynames are the same)
685// 3.Value of each element equal ?
687 const vector< XMLPropertyState >& aProperties1,
688 const vector< XMLPropertyState >& aProperties2 ) const
689{
690 if (aProperties1.size() < aProperties2.size())
691 return true;
692 if (aProperties1.size() > aProperties2.size())
693 return false;
694
695 sal_uInt32 nCount = aProperties1.size();
696
697 for (sal_uInt32 nIndex = 0; nIndex < nCount; ++nIndex)
698 {
699 const XMLPropertyState& rProp1 = aProperties1[ nIndex ];
700 const XMLPropertyState& rProp2 = aProperties2[ nIndex ];
701
702 // Compare index. If equal, compare value
703 if( rProp1.mnIndex < rProp2.mnIndex )
704 return true;
705 if( rProp1.mnIndex > rProp2.mnIndex )
706 return false;
707
708 if( rProp1.mnIndex != -1 )
709 {
710 // Now compare values
711 if ( (mpImpl->mxPropMapper->GetEntryType( rProp1.mnIndex ) &
712 XML_TYPE_BUILDIN_CMP ) != 0 )
713 {
714 // simple type ( binary compare )
715 if ( rProp1.maValue != rProp2.maValue)
716 return false;
717 }
718 else
719 {
720 // complex type ( ask for compare-function )
721 if (!mpImpl->mxPropMapper->GetPropertyHandler(
722 rProp1.mnIndex )->equals( rProp1.maValue,
723 rProp2.maValue ))
724 return false;
725 }
726 }
727 }
728
729 return true;
730}
731
732// Compares two Sequences of XMLPropertyState:
733// 1.Number of elements equal ?
734// 2.Index of each element equal ? (So I know whether the propertynames are the same)
735// 3.Value of each element equal ?
737 const vector< XMLPropertyState >& aProperties1,
738 const vector< XMLPropertyState >& aProperties2 ) const
739{
740 if (aProperties1.size() < aProperties2.size())
741 return true;
742 if (aProperties1.size() > aProperties2.size())
743 return false;
744
745 sal_uInt32 nCount = aProperties1.size();
746
747 for (sal_uInt32 nIndex = 0; nIndex < nCount; ++nIndex)
748 {
749 const XMLPropertyState& rProp1 = aProperties1[ nIndex ];
750 const XMLPropertyState& rProp2 = aProperties2[ nIndex ];
751
752 // Compare index. If equal, compare value
753 if( rProp1.mnIndex < rProp2.mnIndex )
754 return true;
755 if( rProp1.mnIndex > rProp2.mnIndex )
756 return false;
757
758 if( rProp1.mnIndex != -1 )
759 {
760 // Now compare values
761 if ( (mpImpl->mxPropMapper->GetEntryType( rProp1.mnIndex ) &
762 XML_TYPE_BUILDIN_CMP ) != 0 )
763 {
764 // simple type ( binary compare )
765 if ( comphelper::anyLess(rProp1.maValue, rProp2.maValue) )
766 return true;
767 if ( comphelper::anyLess(rProp2.maValue, rProp1.maValue ) )
768 return false;
769 }
770 }
771 }
772
773 return false;
774}
775
800 SvXMLExport& rExport,
801 const ::std::vector< XMLPropertyState >& rProperties,
802 SvXmlExportFlags nFlags,
803 bool bUseExtensionNamespaceForGraphicProperties) const
804{
805 exportXML(rExport, rProperties, -1, -1, nFlags, bUseExtensionNamespaceForGraphicProperties);
806}
807
808
810 SvXMLExport& rExport,
811 const ::std::vector< XMLPropertyState >& rProperties,
812 sal_Int32 nPropMapStartIdx, sal_Int32 nPropMapEndIdx,
813 SvXmlExportFlags nFlags, bool bUseExtensionNamespaceForGraphicProperties) const
814{
815 sal_uInt16 nPropTypeFlags = 0;
816 for( sal_uInt16 i=0; i<MAX_PROP_TYPES; ++i )
817 {
818 sal_uInt16 nPropType = aPropTokens[i].nType;
819 if( 0==i || (nPropTypeFlags & (1 << nPropType)) != 0 )
820 {
821 sal_uInt16 nNamespace = XML_NAMESPACE_STYLE;
822 if (bUseExtensionNamespaceForGraphicProperties &&
824 {
827 {
828 continue; // don't write for ODF <= 1.2
829 }
830 }
831
832 std::vector<sal_uInt16> aIndexArray;
833
834 _exportXML( nPropType, nPropTypeFlags,
835 rExport.GetAttrList(), rProperties,
836 rExport.GetMM100UnitConverter(),
837 rExport.GetNamespaceMap(),
838 &aIndexArray,
839 nPropMapStartIdx, nPropMapEndIdx );
840
841 if( rExport.GetAttrList().getLength() > 0 ||
842 !aIndexArray.empty() )
843 {
844 SvXMLElementExport aElem( rExport, nNamespace,
846 bool(nFlags & SvXmlExportFlags::IGN_WS),
847 false );
848
849 exportElementItems( rExport, rProperties, nFlags, aIndexArray );
850 }
851 }
852 }
853}
854
858 comphelper::AttributeList& rAttrList,
859 const XMLPropertyState& rProperty,
860 const SvXMLUnitConverter& rUnitConverter,
861 const SvXMLNamespaceMap& rNamespaceMap,
862 const ::std::vector< XMLPropertyState > *pProperties,
863 sal_uInt32 nIdx ) const
864{
865 OSL_ENSURE(mpImpl->mxNextMapper.is(), "special item not handled in xml export");
866 if (mpImpl->mxNextMapper.is())
867 mpImpl->mxNextMapper->handleSpecialItem(
868 rAttrList, rProperty, rUnitConverter, rNamespaceMap, pProperties, nIdx);
869}
870
874 SvXMLExport& rExport,
875 const XMLPropertyState& rProperty,
876 SvXmlExportFlags nFlags,
877 const ::std::vector< XMLPropertyState > *pProperties,
878 sal_uInt32 nIdx ) const
879{
880 OSL_ENSURE(mpImpl->mxNextMapper.is(), "element item not handled in xml export");
881 if (mpImpl->mxNextMapper.is())
882 mpImpl->mxNextMapper->handleElementItem(rExport, rProperty, nFlags, pProperties, nIdx);
883}
884
885// protected methods
886
889 sal_uInt16 nPropType, sal_uInt16& rPropTypeFlags,
890 comphelper::AttributeList& rAttrList,
891 const ::std::vector< XMLPropertyState >& rProperties,
892 const SvXMLUnitConverter& rUnitConverter,
893 const SvXMLNamespaceMap& rNamespaceMap,
894 std::vector<sal_uInt16>* pIndexArray,
895 sal_Int32 nPropMapStartIdx, sal_Int32 nPropMapEndIdx ) const
896{
897 const sal_uInt32 nCount = rProperties.size();
898 sal_uInt32 nIndex = 0;
899
900 if( -1 == nPropMapStartIdx )
901 nPropMapStartIdx = 0;
902 if( -1 == nPropMapEndIdx )
903 nPropMapEndIdx = mpImpl->mxPropMapper->GetEntryCount();
904
905 while( nIndex < nCount )
906 {
907 sal_Int32 nPropMapIdx = rProperties[nIndex].mnIndex;
908 if( nPropMapIdx >= nPropMapStartIdx &&
909 nPropMapIdx < nPropMapEndIdx )// valid entry?
910 {
911 sal_uInt32 nEFlags = mpImpl->mxPropMapper->GetEntryFlags(nPropMapIdx);
912 sal_uInt16 nEPType = GET_PROP_TYPE(nEFlags);
913 OSL_ENSURE(nEPType >= (XML_TYPE_PROP_START >> XML_TYPE_PROP_SHIFT),
914 "no prop type specified");
915 rPropTypeFlags |= (1 << nEPType);
916 if( nEPType == nPropType )
917 {
918 // we have a valid map entry here, so lets use it...
919 if( ( nEFlags & MID_FLAG_ELEMENT_ITEM_EXPORT ) != 0 )
920 {
921 // element items do not add any properties,
922 // we export it later
923 if( pIndexArray )
924 {
925 pIndexArray->push_back( static_cast<sal_uInt16>(nIndex) );
926 }
927 }
928 else
929 {
930 _exportXML( rAttrList, rProperties[nIndex], rUnitConverter,
931 rNamespaceMap, &rProperties, nIndex );
932 }
933 }
934 }
935
936 nIndex++;
937 }
938}
939
940namespace
941{
942// -1 = Attribute needs extended namespace, but current ODF version is strict.
943// 1 = Attribute needs extended namespace and current ODF version allows it.
944// 0 = Attribute does not need extended namespace
945sal_Int8 CheckExtendedNamespace(std::u16string_view sXMLAttributeName, std::u16string_view sValue,
947{
948 if (IsXMLToken(sXMLAttributeName, XML_WRITING_MODE)
949 && (IsXMLToken(sValue, XML_BT_LR) || IsXMLToken(sValue, XML_TB_RL90)))
950 return nODFVersion & SvtSaveOptions::ODFSVER_EXTENDED ? 1 : -1;
951 else if (IsXMLToken(sXMLAttributeName, XML_VERTICAL_REL)
953 || IsXMLToken(sValue, XML_PAGE_CONTENT_TOP)))
954 return nODFVersion & SvtSaveOptions::ODFSVER_EXTENDED ? 1 : -1;
955 return 0;
956}
957}
958
960 comphelper::AttributeList& rAttrList,
961 const XMLPropertyState& rProperty,
962 const SvXMLUnitConverter& rUnitConverter,
963 const SvXMLNamespaceMap& rNamespaceMap,
964 const ::std::vector< XMLPropertyState > *pProperties,
965 sal_uInt32 nIdx ) const
966{
967 if ((mpImpl->mxPropMapper->GetEntryFlags(rProperty.mnIndex) & MID_FLAG_SPECIAL_ITEM_EXPORT) != 0)
968 {
969 uno::Reference< container::XNameContainer > xAttrContainer;
970 if( (rProperty.maValue >>= xAttrContainer) && xAttrContainer.is() )
971 {
972 std::unique_ptr<SvXMLNamespaceMap> pNewNamespaceMap;
973 const SvXMLNamespaceMap *pNamespaceMap = &rNamespaceMap;
974
975 const uno::Sequence< OUString > aAttribNames( xAttrContainer->getElementNames() );
976
977 OUStringBuffer sNameBuffer;
978 xml::AttributeData aData;
979 for( const auto& rAttribName : aAttribNames )
980 {
981 xAttrContainer->getByName( rAttribName ) >>= aData;
982 OUString sAttribName( rAttribName );
983
984 // extract namespace prefix from attribute name if it exists
985 OUString sPrefix;
986 const sal_Int32 nColonPos =
987 rAttribName.indexOf( ':' );
988 if( nColonPos != -1 )
989 sPrefix = rAttribName.copy( 0, nColonPos );
990
991 if( !sPrefix.isEmpty() )
992 {
993 OUString sNamespace( aData.Namespace );
994
995 // if the prefix isn't defined yet or has another meaning,
996 // we have to redefine it now.
997 sal_uInt16 nKey = pNamespaceMap->GetKeyByPrefix( sPrefix );
998 if( USHRT_MAX == nKey || pNamespaceMap->GetNameByKey( nKey ) != sNamespace )
999 {
1000 bool bAddNamespace = false;
1001 if( USHRT_MAX == nKey )
1002 {
1003 // The prefix is unused, so it is sufficient
1004 // to add it to the namespace map.
1005 bAddNamespace = true;
1006 }
1007 else
1008 {
1009 // check if there is a prefix registered for the
1010 // namespace URI
1011 nKey = pNamespaceMap->GetKeyByName( sNamespace );
1012 if( XML_NAMESPACE_UNKNOWN == nKey )
1013 {
1014 // There is no prefix for the namespace, so
1015 // we have to generate one and have to add it.
1016 sal_Int32 n=0;
1017 OUString sOrigPrefix( sPrefix );
1018 do
1019 {
1020 sNameBuffer.append( sOrigPrefix );
1021 sNameBuffer.append( ++n );
1022 sPrefix = sNameBuffer.makeStringAndClear();
1023 nKey = pNamespaceMap->GetKeyByPrefix( sPrefix );
1024 }
1025 while( nKey != USHRT_MAX );
1026
1027 bAddNamespace = true;
1028 }
1029 else
1030 {
1031 // If there is a prefix for the namespace,
1032 // we reuse that.
1033 sPrefix = pNamespaceMap->GetPrefixByKey( nKey );
1034 }
1035 // In any case, the attribute name has to be adapted.
1036 sNameBuffer.append(sPrefix + ":" + rAttribName.subView(nColonPos+1));
1037 sAttribName = sNameBuffer.makeStringAndClear();
1038 }
1039
1040 if( bAddNamespace )
1041 {
1042 if( !pNewNamespaceMap )
1043 {
1044 pNewNamespaceMap.reset(new SvXMLNamespaceMap( rNamespaceMap ));
1045 pNamespaceMap = pNewNamespaceMap.get();
1046 }
1047 pNewNamespaceMap->Add( sPrefix, sNamespace );
1048 OUString sAttr = GetXMLToken(XML_XMLNS) + ":" + sPrefix;
1049 rAttrList.AddAttribute( sAttr, sNamespace );
1050 }
1051 }
1052 }
1053 OUString sOldValue( rAttrList.getValueByName( sAttribName ) );
1054 OSL_ENSURE( sOldValue.isEmpty(), "alien attribute exists already" );
1055 OSL_ENSURE(aData.Type == GetXMLToken(XML_CDATA), "different type to our default type which should be written out");
1056 if( sOldValue.isEmpty() )
1057 rAttrList.AddAttribute( sAttribName, aData.Value );
1058 }
1059 }
1060 else
1061 {
1062 handleSpecialItem( rAttrList, rProperty, rUnitConverter,
1063 rNamespaceMap, pProperties, nIdx );
1064 }
1065 }
1066 else if ((mpImpl->mxPropMapper->GetEntryFlags(rProperty.mnIndex) & MID_FLAG_ELEMENT_ITEM_EXPORT ) == 0)
1067 {
1068 OUString aValue;
1069 OUString sName = rNamespaceMap.GetQNameByKey(
1070 mpImpl->mxPropMapper->GetEntryNameSpace(rProperty.mnIndex),
1071 mpImpl->mxPropMapper->GetEntryXMLName(rProperty.mnIndex));
1072
1073 bool bRemove = false;
1074 if ((mpImpl->mxPropMapper->GetEntryFlags( rProperty.mnIndex ) & MID_FLAG_MERGE_ATTRIBUTE) != 0)
1075 {
1076 aValue = rAttrList.getValueByName( sName );
1077 bRemove = true;
1078 }
1079
1080 if (mpImpl->mxPropMapper->exportXML(aValue, rProperty, rUnitConverter))
1081 {
1082 if( bRemove )
1083 rAttrList.RemoveAttribute( sName );
1084
1085 // We don't seem to have a generic mechanism to write an attribute in the extension
1086 // namespace in case of certain attribute values only, so do this manually.
1087 sal_Int8 nExtendedStatus
1088 = CheckExtendedNamespace(mpImpl->mxPropMapper->GetEntryXMLName(rProperty.mnIndex),
1089 aValue, rUnitConverter.getSaneDefaultVersion());
1090 if (nExtendedStatus == -1)
1091 return;
1092 if (nExtendedStatus == 1)
1093 sName = rNamespaceMap.GetQNameByKey(
1094 XML_NAMESPACE_LO_EXT, mpImpl->mxPropMapper->GetEntryXMLName(rProperty.mnIndex));
1095 rAttrList.AddAttribute( sName, aValue );
1096 }
1097 }
1098}
1099
1101 SvXMLExport& rExport,
1102 const ::std::vector< XMLPropertyState >& rProperties,
1103 SvXmlExportFlags nFlags,
1104 const std::vector<sal_uInt16>& rIndexArray ) const
1105{
1106 bool bItemsExported = false;
1107 for (const sal_uInt16 nElement : rIndexArray)
1108 {
1109 OSL_ENSURE( 0 != (mpImpl->mxPropMapper->GetEntryFlags(
1110 rProperties[nElement].mnIndex ) & MID_FLAG_ELEMENT_ITEM_EXPORT),
1111 "wrong mid flag!" );
1112
1113 rExport.IgnorableWhitespace();
1114 handleElementItem( rExport, rProperties[nElement],
1115 nFlags, &rProperties, nElement );
1116 bItemsExported = true;
1117 }
1118
1119 if( bItemsExported )
1120 rExport.IgnorableWhitespace();
1121}
1122
1124{
1125 return mpImpl->mxPropMapper;
1126}
1127
1128void SvXMLExportPropertyMapper::SetStyleName( const OUString& rStyleName )
1129{
1130 mpImpl->maStyleName = rStyleName;
1131}
1132
1134{
1135 return mpImpl->maStyleName;
1136}
1137
1139{
1140 mpImpl->mxPropMapper->GetEntryAPINames(rNames);
1141}
1142
1143/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const PropertyValue * pValues
const XMLTokenEnum aPropTokens[XML_PROP_TYPE_END]
const sal_uInt16 MAX_PROP_TYPES
const OUString & GetStyleName() const
Definition: xmlexppr.cxx:1133
std::unique_ptr< Impl > mpImpl
Definition: xmlexppr.hxx:57
virtual void handleElementItem(SvXMLExport &rExport, const XMLPropertyState &rProperty, SvXmlExportFlags nFlags, const ::std::vector< XMLPropertyState > *pProperties, sal_uInt32 nIdx) const
this method is called for every item that has the MID_FLAG_ELEMENT_EXPORT flag set
Definition: xmlexppr.cxx:873
void ChainExportMapper(const rtl::Reference< SvXMLExportPropertyMapper > &rMapper)
Definition: xmlexppr.cxx:489
bool Equals(const ::std::vector< XMLPropertyState > &aProperties1, const ::std::vector< XMLPropertyState > &aProperties2) const
Compare two arrays of XMLPropertyState.
Definition: xmlexppr.cxx:686
void SetStyleName(const OUString &rStyleName)
Definition: xmlexppr.cxx:1128
virtual void handleSpecialItem(comphelper::AttributeList &rAttrList, const XMLPropertyState &rProperty, const SvXMLUnitConverter &rUnitConverter, const SvXMLNamespaceMap &rNamespaceMap, const ::std::vector< XMLPropertyState > *pProperties, sal_uInt32 nIdx) const
this method is called for every item that has the MID_FLAG_SPECIAL_ITEM_EXPORT flag set
Definition: xmlexppr.cxx:857
SvXMLExportPropertyMapper(const rtl::Reference< XMLPropertySetMapper > &rMapper)
Definition: xmlexppr.cxx:478
void GetEntryAPINames(o3tl::sorted_vector< OUString > &rNames) const
Definition: xmlexppr.cxx:1138
std::vector< XMLPropertyState > FilterDefaults(SvXMLExport const &rExport, const css::uno::Reference< css::beans::XPropertySet > &rPropSet) const
Like Filter(), except that:
Definition: xmlexppr.cxx:528
virtual ~SvXMLExportPropertyMapper() override
Definition: xmlexppr.cxx:485
void exportXML(SvXMLExport &rExport, const ::std::vector< XMLPropertyState > &rProperties, SvXmlExportFlags nFlags, bool bUseExtensionNamespaceForGraphicProperties=false) const
fills the given attribute list with the items in the given set void SvXMLExportPropertyMapper::export...
Definition: xmlexppr.cxx:799
virtual void ContextFilter(bool bEnableFoFontFamily, ::std::vector< XMLPropertyState > &rProperties, const css::uno::Reference< css::beans::XPropertySet > &rPropSet) const
Application-specific filter.
Definition: xmlexppr.cxx:672
std::vector< XMLPropertyState > Filter_(SvXMLExport const &rExport, const css::uno::Reference< css::beans::XPropertySet > &rPropSet, bool bDefault, bool bDisableFoFontFamily, const css::uno::Sequence< OUString > *pOnlyTheseProps) const
Filter all properties we don't want to export: Take all properties of the XPropertySet which are also...
Definition: xmlexppr.cxx:535
void _exportXML(sal_uInt16 nPropType, sal_uInt16 &rPropTypeFlags, comphelper::AttributeList &rAttrList, const ::std::vector< XMLPropertyState > &rProperties, const SvXMLUnitConverter &rUnitConverter, const SvXMLNamespaceMap &rNamespaceMap, std::vector< sal_uInt16 > *pIndexArray, sal_Int32 nPropMapStartIdx, sal_Int32 nPropMapEndIdx) const
fills the given attribute list with the items in the given set
Definition: xmlexppr.cxx:888
std::vector< XMLPropertyState > Filter(SvXMLExport const &rExport, const css::uno::Reference< css::beans::XPropertySet > &rPropSet, bool bEnableFoFontFamily=false, const css::uno::Sequence< OUString > *pOnlyTheseProps=nullptr) const
Filter all properties we don't want to export: Take all properties of the XPropertySet which are also...
Definition: xmlexppr.cxx:519
const rtl::Reference< XMLPropertySetMapper > & getPropertySetMapper() const
Definition: xmlexppr.cxx:1123
void exportElementItems(SvXMLExport &rExport, const ::std::vector< XMLPropertyState > &rProperties, SvXmlExportFlags nFlags, const std::vector< sal_uInt16 > &rIndexArray) const
Definition: xmlexppr.cxx:1100
bool LessPartial(const ::std::vector< XMLPropertyState > &aProperties1, const ::std::vector< XMLPropertyState > &aProperties2) const
Provides a partial ordering over two arrays of XMLPropertyState, Partial because implementing a full ...
Definition: xmlexppr.cxx:736
const SvXMLNamespaceMap & GetNamespaceMap() const
Definition: xmlexp.hxx:385
SvtSaveOptions::ODFSaneDefaultVersion getSaneDefaultVersion() const
returns the deterministic version for odf export
Definition: xmlexp.cxx:2267
void IgnorableWhitespace()
Definition: xmlexp.cxx:2190
const SvXMLUnitConverter & GetMM100UnitConverter() const
Definition: xmlexp.hxx:391
comphelper::AttributeList & GetAttrList()
Definition: xmlexp.hxx:374
OUString GetQNameByKey(sal_uInt16 nKey, const OUString &rLocalName, bool bCache=true) const
const OUString & GetNameByKey(sal_uInt16 nKey) const
sal_uInt16 GetKeyByPrefix(const OUString &rPrefix) const
sal_uInt16 Add(const OUString &rPrefix, const OUString &rName, sal_uInt16 nKey=XML_NAMESPACE_UNKNOWN)
sal_uInt16 GetKeyByName(const OUString &rName) const
const OUString & GetPrefixByKey(sal_uInt16 nKey) const
the SvXMLTypeConverter converts values of various types from their internal representation to the tex...
Definition: xmluconv.hxx:83
SvtSaveOptions::ODFSaneDefaultVersion getSaneDefaultVersion() const
ODF version, only when exporting.
Definition: xmluconv.cxx:124
virtual OUString SAL_CALL getValueByName(const OUString &aName) override
void AddAttribute(const OUString &sName, const OUString &sValue)
virtual sal_Int16 SAL_CALL getLength() override
void RemoveAttribute(const OUString &sName)
int nCount
OUString sPrefix
sal_Int32 nIndex
sal_Int64 n
const char * sName
constexpr OUStringLiteral aData
DRAWING_PAGE
bool anyLess(css::uno::Any const &lhs, css::uno::Any const &rhs)
ns
int i
index
const sal_uInt16 XML_NAMESPACE_UNKNOWN
Handling of tokens in XML:
XMLTokenEnum
The enumeration of all XML tokens.
Definition: xmltoken.hxx:50
@ XML_PAGE_CONTENT_BOTTOM
Definition: xmltoken.hxx:3463
@ XML_GRAPHIC_PROPERTIES
Definition: xmltoken.hxx:2623
bool IsXMLToken(std::u16string_view rString, enum XMLTokenEnum eToken)
compare eToken to the string
Definition: xmltoken.cxx:3580
const OUString & GetXMLToken(enum XMLTokenEnum eToken)
return the OUString representation for eToken
Definition: xmltoken.cxx:3524
QPRO_FUNC_TYPE nType
UNOTOOLS_DLLPUBLIC SvtSaveOptions::ODFDefaultVersion GetODFDefaultVersion()
OReadStatusBarDocumentHandler::StatusBar_XML_Namespace nNamespace
rtl::Reference< XMLPropertySetMapper > mxPropMapper
Definition: xmlexppr.cxx:471
std::map< css::uno::Reference< css::beans::XPropertySetInfo >, std::unique_ptr< FilterPropertiesInfo_Impl > > CacheType
Definition: xmlexppr.cxx:467
rtl::Reference< SvXMLExportPropertyMapper > mxNextMapper
Definition: xmlexppr.cxx:470
Smart struct to transport an Any with an index to the appropriate property-name.
Definition: maptype.hxx:140
css::uno::Any maValue
Definition: maptype.hxx:142
sal_Int32 mnIndex
Definition: maptype.hxx:141
TEXT
bool operator<(const tSchXMLIndexWithPart &rFirst, const tSchXMLIndexWithPart &rSecond)
signed char sal_Int8
TABLE
#define GET_PROP_TYPE(f)
Definition: xmlexppr.cxx:56
#define ENTRY(t)
Definition: xmlexppr.cxx:57
SvXmlExportFlags
Definition: xmlexppr.hxx:41
constexpr sal_uInt16 XML_NAMESPACE_DRAW
constexpr sal_uInt16 XML_NAMESPACE_XHTML
constexpr sal_uInt16 XML_NAMESPACE_META
constexpr sal_uInt16 XML_NAMESPACE_SMIL
constexpr sal_uInt16 XML_NAMESPACE_DC
constexpr sal_uInt16 XML_NAMESPACE_DB
constexpr sal_uInt16 XML_NAMESPACE_XLINK
constexpr sal_uInt16 XML_NAMESPACE_ANIMATION
constexpr sal_uInt16 XML_NAMESPACE_SVG
constexpr sal_uInt16 XML_NAMESPACE_TEXT
constexpr sal_uInt16 XML_NAMESPACE_FORM
constexpr sal_uInt16 XML_NAMESPACE_XFORMS
constexpr sal_uInt16 XML_NAMESPACE_DR3D
constexpr sal_uInt16 XML_NAMESPACE_CHART
constexpr sal_uInt16 XML_NAMESPACE_XML
constexpr sal_uInt16 XML_NAMESPACE_TABLE
constexpr sal_uInt16 XML_NAMESPACE_LO_EXT
constexpr sal_uInt16 XML_NAMESPACE_OFFICE
constexpr sal_uInt16 XML_NAMESPACE_PRESENTATION
constexpr sal_uInt16 XML_NAMESPACE_CONFIG
constexpr sal_uInt16 XML_NAMESPACE_MATH
constexpr sal_uInt16 XML_NAMESPACE_GRDDL
constexpr sal_uInt16 XML_NAMESPACE_STYLE
constexpr sal_uInt16 XML_NAMESPACE_SCRIPT
constexpr sal_uInt16 XML_NAMESPACE_FO
constexpr sal_uInt16 XML_NAMESPACE_NUMBER
XMLTokenEnum eToken
Definition: xmltoken.cxx:40
#define XML_TYPE_PROP_SHIFT
Definition: xmltypes.hxx:90
#define MID_FLAG_ELEMENT_ITEM_EXPORT
Definition: xmltypes.hxx:67
#define MID_FLAG_DEFAULT_ITEM_EXPORT
Definition: xmltypes.hxx:48
#define MID_FLAG_SPECIAL_ITEM_EXPORT
Definition: xmltypes.hxx:86
#define XML_TYPE_BUILDIN_CMP
Definition: xmltypes.hxx:122
#define MID_FLAG_NO_PROPERTY_EXPORT
Definition: xmltypes.hxx:73
#define MID_FLAG_MUST_EXIST
Definition: xmltypes.hxx:52
#define XML_TYPE_PROP_END
Definition: xmltypes.hxx:108
#define MID_FLAG_MERGE_ATTRIBUTE
Definition: xmltypes.hxx:57
#define XML_TYPE_PROP_START
Definition: xmltypes.hxx:93