我有一个关于XML和XSLT的问题:
我有这个生成的xml:
<?xml version="1.0"?>
<rootElement>
<ClassSection>
<Class name="Vehicle" base="Object">
<isPublic />
<isAbstract />
<Field specifier="private" fieldType="Int32" fieldName="numberOfWheels" />
<Field specifier="private" fieldType="Int32" fieldName="numberOfPassengers" />
<Field specifier="private" fieldType="Int32" fieldName="totalVehicleWeight" />
<Field specifier="private" fieldType="Int32" fieldName="emptyVehicleWeight" />
<Field specifier="private" fieldType="String" fieldName="ownerFirstName" />
<Field specifier="private" fieldType="String" fieldName="ownerLastName" />
<Method specifier="public" returnType="Int32" methodName="get_TotalVehicleWeight" />
<Method specifier="public" returnType="void" methodName="set_TotalVehicleWeight">
<Parameter position="0" name="value" type="Int32" />
</Method>
<Method specifier="public" returnType="void" methodName="MovingSound">
<isAbstract />
</Method>
<Method specifier="private" returnType="void" methodName="CalculateVehicleWeight" />
<Method specifier="public" returnType="void" methodName="VehicleOwner">
<Parameter position="0" name="firstname" type="String" />
<Parameter position="1" name="lastName" type="String" />
</Method>
</Class>
<Class name="Car" base="Vehicle">
<isPublic />
<isSealed />
<Field specifier="private" fieldType="String" fieldName="brandName" />
<Field specifier="private" fieldType="Int32" fieldName="amountOfHorsePower" />
<Method specifier="public" returnType="void" methodName="MovingSound" />
</Class>
<Class name="Program" base="Object">
<isPrivate />
</Class>
<Class name="Person" base="Object">
<isPrivate />
<Field specifier="private" fieldType="String" fieldName="firstName" />
<Field specifier="private" fieldType="String" fieldName="lastName" />
<Field specifier="private" fieldType="Int32" fieldName="age" />
<Method specifier="public" returnType="String" methodName="get_FirstName" />
<Method specifier="public" returnType="void" methodName="set_FirstName">
<Parameter position="0" name="value" type="String" />
</Method>
<Method specifier="public" returnType="String" methodName="get_LastName" />
<Method specifier="public" returnType="void" methodName="set_LastName">
<Parameter position="0" name="value" type="String" />
</Method>
<Method specifier="public" returnType="Int32" methodName="get_Age" />
<Method specifier="public" returnType="void" methodName="set_Age">
<Parameter position="0" name="value" type="Int32" />
</Method>
</Class>
</ClassSection>
<InterfaceSection>
<Interface name="ICar">
<isPublic />
<Method returnType="String" methodName="get_ShowBrandName" />
<Method returnType="Void" methodName="set_ShowBrandName">
<Parameter0 name="value" type="String" />
</Method>
<Method returnType="Void" methodName="CreateCar">
<Parameter0 name="timeSpan" type="Int32" />
</Method>
</Interface>
</InterfaceSection>
<EnumSection>
<Enum name="Brands">
<EnumValues>
<BMW />
<MERCEDES />
<AUDI />
</EnumValues>
</Enum>
</EnumSection>
</rootElement>
此XML是C#反射程序的输出。现在,XSLT转换的目标是在XML文件中生成给定对象的集合类。我使用“Person”类来测试它,因为其他类只是在程序的先前版本中为测试目的而制作的一堆奇怪的类。所以我传递了一个变量,该变量声明了我想从哪个类创建一个集合类。我寻找的类的名称是通过XsltArgumentList传递的。之后,XSLT开始了:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:param name="choice"/>
<xsl:template match="Class">
<xsl:if test="@name = $choice">
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
namespace CollectionClassTest001
{
class <xsl:value-of select="$choice"/>Collection
{
//Fields
ArrayList arrayList;
//Properties
public int Length
{
get { return arrayList.Count; }
}
//Constructor
public <xsl:value-of select="$choice"/>Collection()
{
this.arrayList = new ArrayList();
}
//Standard Collection functions
public void Add<xsl:value-of select="$choice"/>(<xsl:value-of select="$choice"/> p)
{
arrayList.Add(p);
}
public void Remove<xsl:value-of select="$choice"/>(<xsl:value-of select="$choice"/> p)
{
arrayList.Remove(p);
}
<xsl:for-each select="Method">
<xsl:apply-templates select="@specifier" />
<xsl:apply-templates select="@returnType" />
<xsl:choose>
<xsl:when test="count(Parameter)!=0">
<xsl:value-of select="@methodName"/>
<xsl:value-of select="Parameter/@name"/>
</xsl:when>
<xsl:when test ="count(Parameter)=0">
<xsl:value-of select="@methodName"/>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:if>
</xsl:template>
<xsl:template match="@specifier">
<xsl:value-of select="."/>
<xsl:text> </xsl:text>
</xsl:template>
<xsl:template match="@returnType">
<xsl:value-of select="."/>
<xsl:if test=". != 'void'">[]</xsl:if>
<xsl:text> </xsl:text>
</xsl:template>
<xsl:template match="@methodName">
<xsl:value-of select="."/>ofAll()
{
}
</xsl:template>
</xsl:stylesheet>
XSLT的第一部分工作正常,但问题始于
<xsl:when test="count(Parameter)!=0">
<xsl:value-of select="./@methodName"/>
<xsl:value-of select="./Parameter/@name"/>
</xsl:when>
输入when clausule有效,但获取Parameter元素的属性“methodName”和“name”的值不起作用。当在VS2010中调试并且命中第一个value-of语句时,debuggere会声明:
self::node() = Method
所以当前的位置是Method。因此,我不明白为什么“./@methodName”失败。现在我必须说我并不完全理解遍历XML的方式以及遍历时当前位置的确定方式。
我试图尽可能清楚,但如果缺少信息,就这么说吧!
谢谢!
P.S。 I:生成集合类的实现还远未完成,因此缺少相当多的东西;)
P.S。 II:我知道,生成集合类是没用的。但是,嘿,学校提出了锻炼,而不是我;)
答案 0 :(得分:1)
这样的事情?
<xsl:variable name="className">Person</xsl:variable>
<xsl:template match="/Class">
<xsl:if test="./@name = $className">
<xsl:apply-templates select="./Method" />
</xsl:if>
</xsl:template>
<xsl:template match="/Class/Method">
<xsl:variable name="function"><xsl:apply-templates select="." mode="function" /></xsl:variable>
<xsl:variable name="parameters"><xsl:apply-templates select="." mode="parameters" /></xsl:variable>
<xsl:value-of select="$function" /> (<xsl:value-of select="$parameters" />)
{
}
</xsl:template>
<xsl:template match="/Class/Method" mode="function">
<xsl:value-of select="./@specifier" /> <xsl:value-of select="./@returnType" /> <xsl:value-of select="./@methodName" />
</xsl:template>
<xsl:template match="/Class/Method" mode="parameters">
<xsl:for-each select="./Parameter">
<xsl:value-of select="./@type" /> <xsl:value-of select="./@name" /><xsl:if test="position() != last()">,</xsl:if>
</xsl:for-each>
</xsl:template>