[Mono-bugs] [Bug 559957] New: node-sets backed by documents need root element in xpath expressions

bugzilla_noreply at novell.com bugzilla_noreply at novell.com
Wed Dec 2 11:52:45 EST 2009


http://bugzilla.novell.com/show_bug.cgi?id=559957

http://bugzilla.novell.com/show_bug.cgi?id=559957#c0


           Summary: node-sets backed by documents need root element in
                    xpath expressions
    Classification: Mono
           Product: Mono: Class Libraries
           Version: SVN
          Platform: x86-64
        OS/Version: openSUSE 11.2
            Status: NEW
          Severity: Normal
          Priority: P5 - None
         Component: Sys.XML
        AssignedTo: atsushi at ximian.com
        ReportedBy: jpryor at novell.com
         QAContact: mono-bugs at lists.ximian.com
          Found By: ---
           Blocker: ---


It's possible to pass a node-set into an XSLT by using an XPathNavigator:

  XDocument doc = ...
  var args = new XsltArgumentList ();
  args.AddParam ("Index", "", doc.CreateNavigator());

Within the XSLT, in .NET if the XPathNavigator comes from a document
(XmlDocument, XDocument) then any XPath expressions must include the root
element

  <xsl:for-each select="$Index/Overview/Types...">

However, Mono does not support this; it needs:

  <xsl:for-each select="$Index/Types/...">

Example:

  using System;
  using System.IO;
  using System.Xml;
  using System.Xml.Linq;
  using System.Xml.XPath;
  using System.Xml.Xsl;

  class Test {
    public static void Main ()
    {
      string xsl =
  @"<xsl:stylesheet version='1.0' 
      exclude-result-prefixes='msxsl'
      xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
      xmlns:msxsl='urn:schemas-microsoft-com:xslt'
      >
    <xsl:param name='Index' />
    <xsl:template match='/'>
      <root>
      <xsl:variable name='t'>
        <xsl:call-template name='get-bar'>
          <xsl:with-param name='type' select=""'Mono.DocTest.Color'"" />
        </xsl:call-template>
      </xsl:variable>
      <xsl:value-of select='msxsl:node-set($t)/Type/@Name' />
      </root>
    </xsl:template>
    <xsl:template name='get-bar'>
      <xsl:param name='type' />
      <xsl:for-each select='$Index/Overview/Types/Namespace/Type'>
        <xsl:variable name='nsp'>
          <xsl:choose>
            <xsl:when test='string-length (parent::Namespace/@Name) = 0' />
            <xsl:otherwise>
              <xsl:value-of select='parent::Namespace/@Name' />
              <xsl:text>.</xsl:text>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:variable>
        <xsl:if test=""concat($nsp, translate(@Name, '+', '.')) = $type"">
          <Type Name='{@Name}' Namespace='{parent::Namespace/@Name}' />
        </xsl:if>
      </xsl:for-each>
    </xsl:template>
  </xsl:stylesheet>";
      var overview = GetOverview ();
      var args = new XsltArgumentList ();
      args.AddParam ("Index", "", overview.CreateNavigator ());
      var t = new XslCompiledTransform ();
      t.Load (new XPathDocument (new StringReader (xsl)));
      t.Transform (
          new XPathDocument (
            new XmlTextReader (
              new StringReader (
                "<root><foo attr='A'/><foo attr='B'/><foo
attr='C'/></root>"))),
          args,
          Console.Out);
      Console.WriteLine();
    }

    static XmlDocument GetOverview ()
    {
      var doc = new XmlDocument ();

      var overview = doc.CreateElement ("Overview");
      doc.AppendChild (overview);

      var types = doc.CreateElement ("Types");
      overview.AppendChild (types);

      var ns = doc.CreateElement ("Namespace");
      types.AppendChild (ns);
      var name = doc.CreateAttribute ("Name");
      name.Value = "Mono.DocTest";
      ns.Attributes.Append (name);

      var t = doc.CreateElement ("Type");
      ns.AppendChild (t);

      name = doc.CreateAttribute ("Name");
      name.Value = "Color";
      t.Attributes.Append (name);
      var k = doc.CreateAttribute ("Kind");
      k.Value = "Enumeration";
      t.Attributes.Append (k);

      return doc;
    }
  }

Under .NET, this prints (ignore the encoding attribute):

  <?xml version="1.0" encoding="IBM437"?><root>Color</root>

Under Mono, this prints:

  <?xml version="1.0" encoding="utf-8"?><root></root>

Note that under Mono, <root/> is empty.

-- 
Configure bugmail: http://bugzilla.novell.com/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug.


More information about the mono-bugs mailing list