1 /* AttributeNode.java --
2 Copyright (C) 2004,2006 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
38 package gnu
.xml
.transform
;
40 import javax
.xml
.XMLConstants
;
41 import javax
.xml
.namespace
.QName
;
42 import javax
.xml
.transform
.TransformerException
;
43 import org
.w3c
.dom
.Document
;
44 import org
.w3c
.dom
.DocumentFragment
;
45 import org
.w3c
.dom
.Attr
;
46 import org
.w3c
.dom
.NamedNodeMap
;
47 import org
.w3c
.dom
.Node
;
48 import gnu
.xml
.xpath
.Expr
;
51 * A template node representing an XSL <code>attribute</code> instruction.
53 * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
55 final class AttributeNode
59 final TemplateNode name
;
60 final TemplateNode namespace
;
63 AttributeNode(TemplateNode name
,
64 TemplateNode namespace
, Node source
)
67 this.namespace
= namespace
;
71 TemplateNode
clone(Stylesheet stylesheet
)
73 TemplateNode ret
= new AttributeNode(name
.clone(stylesheet
),
74 (namespace
== null) ?
null :
75 namespace
.clone(stylesheet
),
78 ret
.children
= children
.clone(stylesheet
);
80 ret
.next
= next
.clone(stylesheet
);
84 void doApply(Stylesheet stylesheet
, QName mode
,
85 Node context
, int pos
, int len
,
86 Node parent
, Node nextSibling
)
87 throws TransformerException
89 Document doc
= (parent
instanceof Document
) ?
(Document
) parent
:
90 parent
.getOwnerDocument();
91 // Create a document fragment to hold the name
92 DocumentFragment fragment
= doc
.createDocumentFragment();
93 // Apply name to the fragment
94 name
.apply(stylesheet
, mode
,
97 // Use XPath string-value of fragment
98 String nameValue
= Expr
.stringValue(fragment
);
100 String namespaceValue
= null;
101 if (namespace
!= null)
103 // Create a document fragment to hold the namespace
104 fragment
= doc
.createDocumentFragment();
105 // Apply namespace to the fragment
106 namespace
.apply(stylesheet
, mode
,
109 // Use XPath string-value of fragment
110 namespaceValue
= Expr
.stringValue(fragment
);
111 if (namespaceValue
.length() == 0)
112 namespaceValue
= null;
115 String prefix
= getPrefix(nameValue
);
116 if (namespaceValue
== null)
120 if (XMLConstants
.XML_NS_PREFIX
.equals(prefix
))
121 namespaceValue
= XMLConstants
.XML_NS_URI
;
124 // Resolve namespace for this prefix
125 namespaceValue
= source
.lookupNamespaceURI(prefix
);
133 String ns2
= source
.lookupNamespaceURI(prefix
);
134 if (ns2
!= null && !ns2
.equals(namespaceValue
))
136 // prefix clashes, reset it
138 int ci
= nameValue
.indexOf(':');
139 nameValue
= nameValue
.substring(ci
+ 1);
145 // Resolve prefix for this namespace
146 prefix
= source
.lookupPrefix(namespaceValue
);
148 nameValue
= prefix
+ ":" + nameValue
;
151 if (namespaceValue
!= null)
153 // Must invent a prefix
154 prefix
= inventPrefix(parent
);
155 nameValue
= prefix
+ ":" + nameValue
;
159 NamedNodeMap attrs
= parent
.getAttributes();
160 boolean insert
= true;
161 if (XMLConstants
.XMLNS_ATTRIBUTE_NS_URI
.equals(namespaceValue
) ||
162 XMLConstants
.XMLNS_ATTRIBUTE
.equals(nameValue
) ||
163 nameValue
.startsWith("xmlns:"))
165 // Namespace declaration, do not output
168 if (prefix
!= null && namespaceValue
== null)
173 if (parent
.getNodeType() == Node
.ELEMENT_NODE
&&
174 parent
.getFirstChild() != null)
176 // XSLT 7.1.3 Adding an attribute to an element after children have
177 // been added to it is an error
183 Attr attr
= (namespaceValue
!= null) ?
184 doc
.createAttributeNS(namespaceValue
, nameValue
) :
185 doc
.createAttribute(nameValue
);
188 if (namespace
!= null)
189 attrs
.setNamedItemNS(attr
);
191 attrs
.setNamedItem(attr
);
193 if (children
!= null)
194 children
.apply(stylesheet
, mode
,
199 next
.apply(stylesheet
, mode
,
201 parent
, nextSibling
);
204 final String
getPrefix(String name
)
206 int ci
= name
.indexOf(':');
207 return (ci
== -1) ?
null : name
.substring(0, ci
);
210 final String
inventPrefix(Node parent
)
214 String ret
= base
+ Integer
.toString(count
);
215 while (parent
.lookupNamespaceURI(ret
) != null)
218 ret
= base
+ Integer
.toString(count
);
223 public boolean references(QName var
)
225 if (name
!= null && name
.references(var
))
227 if (namespace
!= null && namespace
.references(var
))
229 return super.references(var
);
232 public String
toString()
234 StringBuffer buf
= new StringBuffer(getClass().getName());
239 return buf
.toString();