Не удается получить значения из XML с использованием XSLT - PullRequest
2 голосов
/ 09 августа 2010

У меня вопрос по 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>

Ввод условия когда работает, но получение значений атрибутов «methodName» и «name» элемента Parameter не работает. При отладке в VS2010 и выполнении первого оператора value-of отладчик утверждает следующее:

self::node()  =   Method

Итак, текущая позиция - Метод. Поэтому я не понимаю, почему «./@methodName» терпит неудачу. Теперь я должен сказать, что не совсем понимаю, как обходится XML и как определяется текущее положение при обходе.

Я пытался быть максимально ясным, но если информация отсутствует, просто скажите так!

Спасибо!

P.S. I: Реализация для генерации класса коллекции далека от завершения, поэтому некоторые вещи отсутствуют;)

P.S. И.И .: Создание класса коллекции бесполезно, я знаю. Но эй, школа придумывает упражнение, а не я;)

1 Ответ

1 голос
/ 09 августа 2010

как то так?

<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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...