如何使用XSL 1.0的变量和参数

时间:2017-11-24 16:58:01

标签: c# xslt-1.0

当我通过C#学习XSL时出现错误,我不知道如何修复。 我知道有一些XSL语法错误,但我不知道如何修复它,而不是搜索一些XSL文档。 以下是XML / XSL / C#的示例代码。

测试XML文件,Books.xml

<?xml version='1.0'?>
<Books>
    <Publishers>
        <Level1Publishers>
            <PublisherA>
                <Book bid="A1"><Name>Test Book from A</Name></Book>
            </PublisherA>
            <PublisherB>
                <Book bid="B1"><Name>Test Book from B</Name></Book>
            </PublisherB>
        </Level1Publishers>
    </Publishers>
</Books>

XSL文件,Books.xsl

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:param name="PUBLISHER_NAME"/>
<xsl:template match="//Publishers">
  <xsl:variable name="PUBLISHER_PATH" select="./Level1Publishers/$PUBLISHER_NAME/Book"/>
  <Book>
    <BookId>
      <xsl:value-of select="$PUBLISHER_PATH/@bid"/>
    </BookId>
    <Name>
      <xsl:value-of select="$PUBLISHER_PATH/Name"/> 
    </Name>
  </Book>
</xsl:template>
</xsl:stylesheet>

执行转换的C#代码

using System;
using System.IO;
using System.Xml.Xsl;
namespace TestXSL
{
    class Program
    {
        static void Main(string[] ags)
        {
            XsltArgumentList args = new XsltArgumentList();
            args.AddParam("PUBLISHER_NAME", "", "PublisherB");
            XslCompiledTransform xslt = new XslCompiledTransform();
            xslt.Load("Books.xsl");
            StringWriter writer = new StringWriter();
            xslt.Transform("Books.xml", args, writer);
            Console.WriteLine(writer.ToString());
        }
    }
}

它在加载XSL文件时报告异常。

Unhandled Exception: System.Xml.Xsl.XslLoadException: Unexpected token '$' in the expression.
./Level1Publishers/ -->$<-- PUBLISHER_NAME/Book
   at System.Xml.Xsl.XslCompiledTransform.LoadInternal(Object stylesheet, XsltSettings settings, XmlResolver stylesheetResolver)
   at System.Xml.Xsl.XslCompiledTransform.Load(String stylesheetUri)
   at TestXSL.Program.Main(String[] ags) in Program.cs:line 14

然后我按以下方式更改定义PUBLISHER_PATH。

<xsl:variable name="PUBLISHER_PATH" select="concat('./Level1Publishers/',$PUBLISHER_NAME,'/Book')"/>

它报告另一个异常,似乎没有语法错误,但运行时错误

Unhandled Exception: System.Xml.Xsl.XslTransformException: Expression must evaluate to a node-set.
   at System.Xml.Xsl.Runtime.XsltConvert.EnsureNodeSet(IList`1 listItems)
   at <xsl:template match="//Publishers">(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime)
   at <xsl:apply-templates>(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime, XPathNavigator )
   at <xsl:apply-templates>(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime, XPathNavigator )
   at Root(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime)
   at Execute(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime)
   at System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlSequenceWriter results)
   at System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlWriter writer)
   at System.Xml.Xsl.XslCompiledTransform.Transform(String inputUri, XsltArgumentList arguments, TextWriter results)
   at TestXSL.Program.Main(String[] ags) in Program.cs:line 16

1 个答案:

答案 0 :(得分:0)

I hope this helps you.

<xsl:param name="PUBLISHER_NAME"/>

<xsl:template match="//Publishers/Level1Publishers">
  <Book>
    <BookId>
      <xsl:value-of select=".//Book[Name=$PUBLISHER_NAME]/@bid"/>
    </BookId>
    <Name>
      <xsl:value-of select="$PUBLISHER_NAME"/>
    </Name>
  </Book>
</xsl:template>


<xsl:template match="node()">
  <xsl:apply-templates/>
</xsl:template>