Question

I have an XML file that I am transforming via XSLT. I am passing an XML as parameter to the XSLT via C#. The parameter's name is attachment and it contains XML. It is written as follows:

StringWriter sw = new StringWriter(); 
XmlTextWriter w = new XmlTextWriter(sw); 
w.WriteStartElement("root"); 
if (!string.IsNullOrEmpty(sWordFileName)) { 
    w.WriteStartElement("mylink", sWordFileName); 
    w.WriteEndElement(); 
}
if (!string.IsNullOrEmpty(sPDFFileName)) { 
    w.WriteStartElement("mylink", sPDFFileName);
    w.WriteEndElement();
}
w.Close();
XPathDocument doc = new XPathDocument(new StringReader(sw.ToString()));
XPathNavigator nav = doc.CreateNavigator();
_exportSet[currentExportSet].Format.ParamList["attachment"] = nav.Select("./*");

My xml parameter looks like

<root><attachment xmlns=file1><attachment xmlns=file2></root>

Now in XSLT I need to iterate through this XML param and create a link.

Here is my XSLT

<?xml version="1.0" encoding="utf-8"?> 
    <xsl:stylesheet version="2.0" xmlns:xsl="w3.org/1999/XSL/Transform"
        xmlns:msxsl="urn:schemas-microsoft-com:xslt" 
        xmlns:my-scripts="urn:my-scripts" 
        xmlns="factiva.com/fcs/schemas/newsSummaries">

        <xsl:param name="attachment"/>
        <xsl:for-each select="$attachment">  
            <a target="_blank" href="#"><xsl:copy-of select="."/></a>  
         </xsl:for-each>
     </xsl:stylesheet>

But it doesn't create a link.

Était-ce utile?

La solution

An XSLT parameter is different than an XML tag name. Parameters are passed using the tag as described here.

As stated in the comments below, this problem is not too different from what is provided in the link above.

StringWriter sw = new StringWriter(); 
XmlTextWriter w = new XmlTextWriter(sw); 
w.WriteStartElement("root"); 
if (!string.IsNullOrEmpty(sWordFileName)) { 
    w.WriteStartElement("attachment", sWordFileName); 
    w.WriteAttributeString("name", sWordFileName);
    w.WriteEndElement(); 
}
if (!string.IsNullOrEmpty(sPDFFileName)) { 
    w.WriteStartElement("attachment");
    w.WriteAttributeString("name", sPDFFileName);
    w.WriteEndElement();
}
w.WriteEndElement();
w.Close();
XPathDocument doc = new XPathDocument(new StringReader(sw.ToString()));
XPathNavigator nav = doc.CreateNavigator();

XsltArgumentList xslArg = new XsltArgumentList();
xslArg.AddParam("attachment","",nav);

Here would be XSL to match per Accessing parameters which contain mark-up:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" 
   xmlns:xsl="w3.org/1999/XSL/Transform"
   xmlns:msxsl="urn:schemas-microsoft-com:xslt" 
   xmlns:my-scripts="urn:my-scripts" 
   xmlns="factiva.com/fcs/schemas/newsSummaries">
    <xsl:param name="attachment" />

    <xsl:template match="/">
        <xsl:apply-templates select="$attachment"/>
    </xsl:template>
    <xsl:template match="attachment">
        <a target="_blank" href="{@name}">{@name}</a>
    </xsl:template>

</xsl:stylesheet>

Autres conseils

You can pass any XPath/XSLT data type as parameters. How to do that entirely depends on the XSLT processor implementation.

As proof this stylesheet, with any input (not used):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:param name="attachment" select="document('parameter.xml')/root"/>
    <xsl:template match="/">
        <xsl:apply-templates select="$attachment"/>
    </xsl:template>
    <xsl:template match="attachment">
        <a target="_blank" href="{@href}">Link</a>
    </xsl:template>
</xsl:stylesheet>

And parameter.xml resource as:

<root>
    <attachment href="file1"/>
    <attachment href="file2"/>
</root> 

Output:

<a target="_blank" href="file1">Link</a>
<a target="_blank" href="file2">Link</a>

It should read <xsl:for-each select="attachment">.... There is no $ sign because attachment is the name of an XML element, not a variable.


EDIT after you've given the full XSLT and XML.

There are several problems with your XML:

  • All tags should be closed.
  • You may not use the xmlns for anything else that it's meant for — namespaces.
  • You must have double quotes around the attribute values

So a correct version of the XML file would be (for instance):

<root>
  <attachment ptr="file1" />
  <attachment ptr="file2" />
</root>

The XSLT file has some issues too:

  • The xsl namespace should be bound to the exact URI http://www.w3.org/1999/XSL/Transform.
  • You must have at least a template so that the XSLT transform processes your input XML document.

A correct version would be, for instance:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/root">
    <xsl:for-each select="attachment">  
      <a target="_blank" href="{@ptr}"><xsl:value-of select="@ptr" /></a>  
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

I'm not sure it is exactly what you want, but for the above document it produces the following fragment:

<a target="_blank" href="file1">file1</a>
<a target="_blank" href="file2">file2</a>

You would want to put the value of your attribute that has the link in it like so:

<xsl:value-of select="@YourAttribute"/>

This selects an attribute for the current xml element.

The code you posted is somewhat incorrect. Where are the quotes, what is $attachment? You probably forgot to mention namespace, to select correctly, you need to write select="//file1:attachment" or sth like that.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top