XSLT总和来自另一个文件的查找值

时间:2011-05-20 11:48:04

标签: xslt sum lookup multifile

我想从以下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 个答案:

答案 0 :(得分:3)

这是一个简单易用的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() 功能。

答案 1 :(得分:0)

在下面的转换中,我首先使用收集的值构建变量,然后使用XPath sum()函数来获取结果。它不像@Dimitre方法那样优雅和聪明,但无论如何我还想发帖:)


Saxon-HE 9.2.1.1J 下测试

XSLT 2.0

<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

答案 2 :(得分:-1)

试试这个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());
      }
 }