Sum of XSLT by search value from another file

I want the total number of a particular student from two XML files:

--- File: mark.xml ----

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

--- File: 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> 

How can I get a general grade for a student with id 1234 ? he should be 15.

+4
source share
3 answers

Here is a short and simple XSLT solution (actually it's just 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> 

when this conversion is applied to the provided XML document (named "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> 

Found the desired answer :

 15 

If you want to save the label values ​​in a separate file (not built into the XSLT stylesheet, as indicated above), the XPath expression should be slightly modified (only the argument to the document() function:

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

Explanation

+3
source

In the next conversion, I first create a variable with the collected values, and then use the XPath sum() function to get the result. It's not as elegant and smart as the @Dimitre approach, but I would like to post it anyway :)


XSLT 2.0 is tested in 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> 

The result applied to the input presented in the question is just the sum:

  15 
0
source

Try this C # code:

  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()); } } 
-1
source

All Articles