01: /*
02: * Licensed to the Apache Software Foundation (ASF) under one or more
03: * contributor license agreements. See the NOTICE file distributed with
04: * this work for additional information regarding copyright ownership.
05: * The ASF licenses this file to You under the Apache License, Version 2.0
06: * (the "License"); you may not use this file except in compliance with
07: * the License. You may obtain a copy of the License at
08: *
09: * http://www.apache.org/licenses/LICENSE-2.0
10: *
11: * Unless required by applicable law or agreed to in writing, software
12: * distributed under the License is distributed on an "AS IS" BASIS,
13: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14: * See the License for the specific language governing permissions and
15: * limitations under the License.
16: */
17: package org.apache.cocoon.xml;
18:
19: import org.xml.sax.Attributes;
20: import org.xml.sax.SAXException;
21:
22: /**
23: * A SAX filter that strips out redundant namespace declarations.
24: *
25: * <p>
26: * It handles both duplicate declarations (i.e. a namespace already declared by a
27: * parent element) and empty namespaces scopes (i.e. start/stopPrefixMapping with
28: * no element inbetween) that can be produced by some components (e.g. JXTG or
29: * BrowserUpdateTransformer). Such empty scopes confuse the Xalan serializer which
30: * then produces weird namespace declarations (<code>xmlns:%@$#^@#="%@$#^@#"</code>).
31: *
32: * <p>
33: * This is a the most simple use of {@link NamespacesTable}.
34: *
35: * @version CVS $Id: RedundantNamespacesFilter.java 433543 2006-08-22 06:22:54Z crossley $
36: */
37: public class RedundantNamespacesFilter extends AbstractXMLPipe {
38:
39: /** Layered storage for all namespace declarations */
40: private NamespacesTable ns = new NamespacesTable();
41:
42: /**
43: * No-arg constructor. Requires an explicit call to
44: * <code>setConsumer()</code>.
45: */
46: public RedundantNamespacesFilter() {
47: // Nothing
48: }
49:
50: /**
51: * Creates a filter directly linked to its consumer
52: *
53: * @param consumer
54: * the SAX stream consumer
55: */
56: public RedundantNamespacesFilter(XMLConsumer consumer) {
57: setConsumer(consumer);
58: }
59:
60: public void startPrefixMapping(String prefix, String uri)
61: throws SAXException {
62: // Just declare it: duplicate declarations are ignorede by NamespacesTable
63: ns.addDeclaration(prefix, uri);
64: }
65:
66: public void startElement(String uri, String loc, String raw,
67: Attributes a) throws SAXException {
68: // Declare namespaces for this scope, if any
69: ns.enterScope(this .contentHandler);
70: super .startElement(uri, loc, raw, a);
71: }
72:
73: public void endElement(String uri, String loc, String raw)
74: throws SAXException {
75: super .endElement(uri, loc, raw);
76: ns.leaveScope(this .contentHandler);
77: }
78:
79: public void endPrefixMapping(String prefix) throws SAXException {
80: ns.removeDeclaration(prefix);
81: }
82: }
|