Сумма XSLT по значению поиска из другого файла - PullRequest
4 голосов
/ 20 мая 2011

Я хочу получить общее количество конкретного ученика из следующих 2 файлов XML:

--- Файл: mark.xml ----

<marks>
  <mark type="HD">10</mark>
  <mark type="D">8</mark>
  <mark type="C">5</mark>
</marks>

--- Файл: studentRecord.xml ---

<students>
  <student id="1234">
    <grade>HD</grade>
  </student>
  <student id="1234">
    <grade>C</grade>
  </student>
  <student id="1111">
    <grade>D</grade>
  </student>
</students>

Как я могу получить общую оценку студента, имеющего id 1234? должно быть 15.

Ответы [ 3 ]

3 голосов
/ 20 мая 2011

Вот краткое и простое решение XSLT (на самом деле это просто XPath):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my">
 <xsl:output method="text"/>

 <my:MarkValues>
        <marks>
            <mark type="HD">10</mark>
            <mark type="D">8</mark>
            <mark type="C">5</mark>
        </marks>
 </my:MarkValues>

 <xsl:template match="/*">
     <xsl:value-of select=
     "sum(document('')/*
           /my:MarkValues/*/*
               [@type = current()/*
                          [@id='1234']/grade
             ]
        )"/>
 </xsl:template>
</xsl:stylesheet>

когда это преобразование применяется к предоставленному документу XML (с именем "studentRecord.xml"):

<students>
    <student id="1234">
        <grade>HD</grade>
    </student>
    <student id="1234">
        <grade>C</grade>
    </student>
    <student id="1111">
        <grade>D</grade>
    </student>
</students>

желаемый ответ выдается :

15

Если вы хотите сохранить значения меток в отдельном файле (не включенном в таблицу стилей XSLT, как указано выше), выражение XPath должно быть слегка изменено (только аргумент document() функция:

sum(document('mark.xml')/*/*
                     [@type = current()/*
                                     [@id='1234']/grade
                     ]
   )

Объяснение

  1. Использование функции XSLT document().

  2. Использование функции XSLT current().

  3. Использование функции XPath sum().

0 голосов
/ 20 мая 2011

В следующем преобразовании я сначала строю переменную с собранными значениями, а затем для получения результата используется функция XPath sum().Это не так элегантно и умно, как подход @Dimitre, но я все равно хотел бы опубликовать:)


XSLT 2.0 протестировано под Saxon-HE 9.2.1.1J

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>   

    <xsl:variable name="lookup" select="document('lookup.xml')/marks"/> 

    <xsl:template match="students">

        <xsl:variable name="values">
            <values>
                <xsl:for-each select="student[@id='1234']">
                    <value><xsl:value-of select="$lookup/mark[@type=current()/grade]"/></value>
                </xsl:for-each>
            </values>
        </xsl:variable>

        <xsl:value-of select="sum($values//value)"/>

    </xsl:template>

</xsl:stylesheet>

Результат, примененный к входным данным, представленным в вопросе, является просто суммой:

 15
0 голосов
/ 20 мая 2011

Попробуйте этот код C #:

 var studenst = XElement.Load("studentRecord.xml");
 var marks= XElement.Load("marks.xml");

 Dictionary<string, int> marksDic = new Dictionary<string, int>();
 foreach (XElement m in marks.Descendants())
      {
           if (m.Attribute("type") != null)
                marksDic.Add(m.Attribute("type").Value, int.Parse(m.Value));
      }


      foreach (XElement s in studenst.Descendants().Where(x=>(x.Attribute("id") !=null ?int.Parse(x.Attribute("id").Value):0)==id))
      {

           Console.WriteLine(marksDic.Where(x => x.Key == s.Value)
                .Select(x => x.Value).Single());
      }
 }
...