Procházet zdrojové kódy

2008-01-08 Atsushi Enomoto <[email protected]>

	* XslKey.cs, XslStylesheet.cs, Compiler.cs : XSLT 1.0 does not
	  prohibit more than one xsl:key with the same QName, so do not use
	  the name as a 'key' in the table for xsl:key. Fixed bug #351939,
	  patch by Tor Lillqvist.

	* XslTransformTests.cs : added test from bug #351939.
	  (by Tor Lillqvist)


svn path=/trunk/mcs/; revision=92426
Atsushi Eno před 18 roky
rodič
revize
ea6e3df631

+ 7 - 0
mcs/class/System.XML/Mono.Xml.Xsl/ChangeLog

@@ -1,3 +1,10 @@
+2008-01-08  Atsushi Enomoto  <[email protected]>
+
+	* XslKey.cs, XslStylesheet.cs, Compiler.cs : XSLT 1.0 does not
+	  prohibit more than one xsl:key with the same QName, so do not use
+	  the name as a 'key' in the table for xsl:key. Fixed bug #351939,
+	  patch by Tor Lillqvist.
+
 2007-12-27  Atsushi Enomoto  <[email protected]>
 
 	* XslTemplate.cs, XslTransformProcessor.cs :

+ 5 - 3
mcs/class/System.XML/Mono.Xml.Xsl/Compiler.cs

@@ -91,9 +91,9 @@ namespace Mono.Xml.Xsl
 			return (XslGeneralVariable)globalVariables [name];
 		}
 		
-		public XslKey ResolveKey (QName name)
+		public ArrayList ResolveKey (QName name)
 		{
-			return (XslKey) keys [name];
+			return (ArrayList) keys [name];
 		}
 		
 		public XslAttributeSet ResolveAttributeSet (QName name)
@@ -426,7 +426,9 @@ namespace Mono.Xml.Xsl
 
 		public void AddKey (XslKey key)
 		{
-			keys [key.Name] = key;
+			if (keys [key.Name] == null)
+				keys [key.Name] = new ArrayList ();
+			((ArrayList) keys [key.Name]).Add (key);
 		}
 
 		public void AddAttributeSet (XslAttributeSet set)

+ 17 - 5
mcs/class/System.XML/Mono.Xml.Xsl/XslKey.cs

@@ -99,20 +99,26 @@ namespace Mono.Xml.Xsl
 	internal class KeyIndexTable
 	{
 		XsltCompiledContext ctx;
-		XslKey key;
+		ArrayList keys;
 		Hashtable mappedDocuments;
 
-		public KeyIndexTable (XsltCompiledContext ctx, XslKey key)
+		public KeyIndexTable (XsltCompiledContext ctx, ArrayList keys)
 		{
 			this.ctx = ctx;
-			this.key = key;
+			this.keys = keys;
 		}
 
-		public XslKey Key {
-			get { return key; }
+		public ArrayList Keys {
+			get { return keys; }
 		}
 
 		private void CollectTable (XPathNavigator doc, XsltContext ctx, Hashtable map)
+		{
+			for (int i = 0; i < keys.Count; i++)
+				CollectTable (doc, ctx, map, (XslKey) keys[i]);
+		}
+
+		private void CollectTable (XPathNavigator doc, XsltContext ctx, Hashtable map, XslKey key)
 		{
 			XPathNavigator nav = doc.Clone ();
 			nav.MoveToRoot ();
@@ -159,6 +165,12 @@ namespace Mono.Xml.Xsl
 		}
 
 		private void CollectIndex (XPathNavigator nav, XPathNavigator target, Hashtable map)
+		{
+			for (int i = 0; i < keys.Count; i++)
+				CollectIndex (nav, target, map, (XslKey) keys[i]);
+		}
+
+		private void CollectIndex (XPathNavigator nav, XPathNavigator target, Hashtable map, XslKey key)
 		{
 			XPathNodeIterator iter;
 			switch (key.Use.ReturnType) {

+ 7 - 4
mcs/class/System.XML/Mono.Xml.Xsl/XslStylesheet.cs

@@ -57,7 +57,7 @@ namespace Mono.Xml.Xsl {
 		NameValueCollection namespaceAliases = new NameValueCollection ();
 		// [QName]=>XmlSpace
 		Hashtable parameters = new Hashtable ();
-		// [QName]=>XslKey
+		// [QName]=>ArrayList of XslKey
 		Hashtable keys = new Hashtable();
 		// [QName]=>XslVariable
 		Hashtable variables = new Hashtable ();
@@ -162,8 +162,9 @@ namespace Mono.Xml.Xsl {
 
 			foreach (XslGlobalVariable v in variables.Values)
 				c.AddGlobalVariable (v);
-			foreach (XslKey key in keys.Values)
-				c.AddKey (key);
+			foreach (ArrayList al in keys.Values)
+				for (int i = 0; i < al.Count; i++)
+					c.AddKey ((XslKey) al[i]);
 
 			c.PopStylesheet ();
 			inProcessIncludes = null;
@@ -436,7 +437,9 @@ namespace Mono.Xml.Xsl {
 
 				case "key":
 					XslKey key = new XslKey (c);
-					keys [key.Name] = key;
+					if (keys [key.Name] == null)
+						keys [key.Name] = new ArrayList ();
+					((ArrayList) keys [key.Name]).Add (key);
 					break;
 					
 				case "output":

+ 5 - 0
mcs/class/System.XML/Test/System.Xml.Xsl/ChangeLog

@@ -1,3 +1,8 @@
+2008-01-08  Atsushi Enomoto  <[email protected]>
+
+	* XslTransformTests.cs : added test from bug #351939.
+	  (by Tor Lillqvist)
+
 2007-12-27  Atsushi Enomoto  <[email protected]>
 
 	* XslTransformTests.cs : added test for bug #349375. (Actually the

+ 34 - 0
mcs/class/System.XML/Test/System.Xml.Xsl/XslTransformTests.cs

@@ -2063,6 +2063,40 @@ Services
 			Assert.AreEqual (expected, sw.ToString ());
 		}
 
+		[Test]
+		public void Bug351939 ()
+		{
+			XslTransform xslt = new XslTransform ();
+			xslt.Load (new XmlTextReader (new StringReader (
+@"<xsl:stylesheet version=""1.0""
+  xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"">
+  <xsl:key name=""thekey"" match=""aa"" use=""''""/>
+  <xsl:key name=""thekey"" match=""ab"" use=""''""/>
+  <xsl:template match=""root"">
+    <x>
+      <foo><xsl:value-of select=""key('thekey','')[1]""/></foo>
+      <bar><xsl:value-of select=""key('thekey','')[2]""/></bar>
+      <baz><xsl:value-of select=""key('thekey','')[3]""/></baz>
+      <tem><xsl:value-of select=""key('thekey','')[4]""/></tem>
+    </x>
+  </xsl:template>
+</xsl:stylesheet>")));
+			StringWriter sw = new StringWriter ();
+			xslt.Transform (new XPathDocument (new StringReader (
+@"<?xml version=""1.0""?>
+<root>
+  <a>
+    <aa>1</aa>
+    <ab>2</ab>
+  </a>
+  <a>
+    <aa>3</aa>
+    <ab>4</ab>
+  </a>
+</root>")), null, new XmlTextWriter (sw));
+			Assert.AreEqual ("<x><foo>1</foo><bar>2</bar><baz>3</baz><tem>4</tem></x>", sw.ToString ());
+		}
+
 #if NET_2_0
 		[Test] // bug #349375
 		public void PreserveWhitespace ()