1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_xmloff.hxx" 26 #include "TokenContext.hxx" 27 #include <xmloff/xmltkmap.hxx> 28 #include <xmloff/xmlimp.hxx> 29 #include <xmloff/nmspmap.hxx> 30 #include "xmloff/xmlerror.hxx" 31 32 #include <tools/debug.hxx> 33 34 using rtl::OUString; 35 using com::sun::star::uno::Reference; 36 using com::sun::star::xml::sax::XAttributeList; 37 38 39 struct SvXMLTokenMapEntry aEmptyMap[1] = 40 { 41 XML_TOKEN_MAP_END 42 }; 43 44 45 TokenContext::TokenContext( SvXMLImport& rImport, 46 sal_uInt16 nPrefix, 47 const OUString& rLocalName, 48 const SvXMLTokenMapEntry* pAttributes, 49 const SvXMLTokenMapEntry* pChildren ) 50 : SvXMLImportContext( rImport, nPrefix, rLocalName ), 51 mpAttributes( pAttributes ), 52 mpChildren( pChildren ) 53 { 54 } 55 56 TokenContext::~TokenContext() 57 { 58 } 59 60 void TokenContext::StartElement( 61 const Reference<XAttributeList>& xAttributeList ) 62 { 63 // iterate over attributes 64 // - if in map: call HandleAttribute 65 // - xmlns:... : ignore 66 // - other: warning 67 DBG_ASSERT( mpAttributes != NULL, "no token map for attributes" ); 68 SvXMLTokenMap aMap( mpAttributes ); 69 70 sal_Int16 nCount = xAttributeList->getLength(); 71 for( sal_Int16 i = 0; i < nCount; i++ ) 72 { 73 // get key/local-name pair from namespace map 74 OUString sLocalName; 75 sal_uInt16 nPrefix = GetImport().GetNamespaceMap(). 76 GetKeyByAttrName( xAttributeList->getNameByIndex(i), &sLocalName ); 77 78 // get token from token map 79 sal_uInt16 nToken = aMap.Get( nPrefix, sLocalName ); 80 81 // and the value... 82 const OUString& rValue = xAttributeList->getValueByIndex(i); 83 84 if( nToken != XML_TOK_UNKNOWN ) 85 { 86 HandleAttribute( nToken, rValue ); 87 } 88 else if( nPrefix != XML_NAMESPACE_XMLNS ) 89 { 90 // error handling, for all attribute that are not 91 // namespace declarations 92 GetImport().SetError( XMLERROR_UNKNOWN_ATTRIBUTE, 93 sLocalName, rValue); 94 } 95 } 96 } 97 98 SvXMLImportContext* TokenContext::CreateChildContext( 99 sal_uInt16 nPrefix, 100 const OUString& rLocalName, 101 const Reference<XAttributeList>& xAttrList ) 102 { 103 // call HandleChild for elements in token map. Ignore other content. 104 105 SvXMLImportContext* pContext = NULL; 106 107 DBG_ASSERT( mpChildren != NULL, "no token map for child elements" ); 108 SvXMLTokenMap aMap( mpChildren ); 109 sal_uInt16 nToken = aMap.Get( nPrefix, rLocalName ); 110 if( nToken != XML_TOK_UNKNOWN ) 111 { 112 // call handle child, and pass down arguments 113 pContext = HandleChild( nToken, nPrefix, rLocalName, xAttrList ); 114 } 115 116 // error handling: create default context and generate warning 117 if( pContext == NULL ) 118 { 119 GetImport().SetError( XMLERROR_UNKNOWN_ELEMENT, rLocalName ); 120 pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName ); 121 } 122 return pContext; 123 } 124 125 bool lcl_IsWhiteSpace( sal_Unicode c ) 126 { 127 return c == sal_Unicode( ' ' ) 128 || c == sal_Unicode( 0x09 ) 129 || c == sal_Unicode( 0x0A ) 130 || c == sal_Unicode( 0x0D ); 131 } 132 133 void TokenContext::Characters( const ::rtl::OUString& rCharacters ) 134 { 135 // get iterators for string data 136 const sal_Unicode* pBegin = rCharacters.getStr(); 137 const sal_Unicode* pEnd = &( pBegin[ rCharacters.getLength() ] ); 138 139 // raise error if non-whitespace character is found 140 if( ::std::find_if( pBegin, pEnd, ::std::not1(::std::ptr_fun(lcl_IsWhiteSpace)) ) != pEnd ) 141 GetImport().SetError( XMLERROR_UNKNOWN_CHARACTERS, rCharacters ); 142 } 143