5 // Ben Maurer (bmaurer@users.sourceforge.net)
6 // Atsushi Enomoto (ginga@kit.hi-ho.ne.jp)
9 // (C) 2003 Atsushi Enomoto
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 using System
.Collections
;
36 using System
.Xml
.XPath
;
40 using QName
= System
.Xml
.XmlQualifiedName
;
42 namespace Mono
.Xml
.Xsl
.Operations
{
43 internal class XslAttribute
: XslCompiledElement
{
45 string calcName
, calcNs
, calcPrefix
;
46 XmlNamespaceManager nsm
;
51 public XslAttribute (Compiler c
) : base (c
) {}
53 protected override void Compile (Compiler c
)
55 nav
= c
.Input
.Clone ();
57 name
= c
.ParseAvtAttribute ("name");
59 throw new XsltCompileException ("attribute \"name\" is required on XSLT attribute element.", null, c
.Input
);
60 ns
= c
.ParseAvtAttribute ("namespace");
62 calcName
= XslAvt
.AttemptPreCalc (ref name
);
63 calcPrefix
= String
.Empty
;
65 if (calcName
!= null) {
66 int colonAt
= calcName
.IndexOf (':');
67 calcPrefix
= colonAt
< 0 ? String
.Empty
: calcName
.Substring (0, colonAt
);
68 calcName
= colonAt
< 0 ? calcName
: calcName
.Substring (colonAt
+ 1, calcName
.Length
- colonAt
- 1);
71 XmlConvert
.VerifyNCName (calcName
);
72 if (calcPrefix
!= String
.Empty
)
73 XmlConvert
.VerifyNCName (calcPrefix
);
74 } catch (XmlException ex
) {
75 throw new XsltCompileException ("Invalid attribute name.", ex
, c
.Input
);
78 if (calcPrefix
!= String
.Empty
&& ns
== null)
79 calcNs
= nav
.GetNamespace (calcPrefix
);
81 calcNs
= XslAvt
.AttemptPreCalc (ref ns
);
83 if (calcNs
==null && calcPrefix
!= String
.Empty
) {
84 string test
= c
.CurrentStylesheet
.PrefixInEffect (calcPrefix
, null);
86 string alias = c
.CurrentStylesheet
.NamespaceAliases
[calcPrefix
] as string;
88 calcNs
= c
.Input
.GetNamespace (alias);
90 calcNs
= c
.Input
.NamespaceURI
;
94 if (ns
== null && calcNs
== null)
97 if (c
.Input
.MoveToFirstChild ()) {
98 value = c
.CompileTemplateContent (XPathNodeType
.Attribute
);
99 c
.Input
.MoveToParent ();
104 public override void Evaluate (XslTransformProcessor p
)
106 string nm
, nmsp
, prefix
;
108 nm
= calcName
!= null ? calcName
: name
.Evaluate (p
);
109 nmsp
= calcNs
!= null ? calcNs
: ns
!= null ? ns
.Evaluate (p
) : String
.Empty
;
110 prefix
= calcPrefix
!= null ? calcPrefix
: String
.Empty
;
113 // It is an error. We must recover by not emmiting any attributes
114 // (unless we throw an exception).
117 int colonAt
= nm
.IndexOf (':');
120 prefix
= nm
.Substring (0, colonAt
);
121 nm
= nm
.Substring (colonAt
+ 1, nm
.Length
- colonAt
- 1);
125 QName q
= XslNameUtil
.FromString (nm
, nsm
);
129 nm
= XslNameUtil
.LocalNameOf (nm
);
132 if (nmsp
!= String
.Empty
&& prefix
== String
.Empty
) {
133 if (nav
.MoveToFirstNamespace (XPathNamespaceScope
.ExcludeXml
)) {
135 if (nav
.Value
== nmsp
) {
139 } while (nav
.MoveToNextNamespace (XPathNamespaceScope
.ExcludeXml
));
144 if (prefix
== "xmlns")
145 prefix
= String
.Empty
; // Should not be allowed.
147 XmlConvert
.VerifyName (nm
);
150 p
.Out
.WriteAttributeString(prefix
, nm
, nmsp
, "");
152 StringWriter sw
= new StringWriter ();
153 Outputter outputter
= new TextOutputter (sw
, true);
154 p
.PushOutput (outputter
);
158 p
.Out
.WriteAttributeString (prefix
, nm
, nmsp
, sw
.ToString ());