Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
XSLT通过另一个文件中的查找值求和_Xslt_Sum_Lookup_Multifile - Fatal编程技术网

XSLT通过另一个文件中的查找值求和

XSLT通过另一个文件中的查找值求和,xslt,sum,lookup,multifile,Xslt,Sum,Lookup,Multifile,我想从以下2个XML文件中获取特定学生的总数: ---文件:mark.xml---- 如何获得id为1234的学生的总分?应该是15 试试这个C代码: var studenst=XElement.Load(“studentRecord.xml”); var marks=XElement.Load(“marks.xml”); 字典标记dic=新字典(); foreach(marks.substands()中的元素m) { 如果(m.Attribute(“type”)!=null) 添加(m.Att

我想从以下2个XML文件中获取特定学生的总数:

---文件:
mark.xml
----

如何获得id为1234的学生的总分?应该是15

试试这个C代码:

var studenst=XElement.Load(“studentRecord.xml”);
var marks=XElement.Load(“marks.xml”);
字典标记dic=新字典();
foreach(marks.substands()中的元素m)
{
如果(m.Attribute(“type”)!=null)
添加(m.Attribute(“type”).Value,int.Parse(m.Value));
}
foreach(studenst.subjects()中的元素s,其中(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());
}
}

这里有一个简单的XSLT解决方案(实际上它只是XPath):

如果希望将标记值保留在单独的文件中(不嵌入XSLT样式表中,如上所述),XPath表达式应该稍微更改(只需
document()
函数的参数:

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

15
  • 使用XSLT函数

  • 使用XSLT函数

  • 使用XPath函数


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


    XSLT2.0在萨克森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>
    

    您正在使用什么编程环境/技术?XSLT是否执行多文件查询?我认为您需要XQuery(或某种主机环境)来实现这一点。首先将两个文件合并为一个文件是否可行?好问题+1.请参阅我的答案,了解一个完整、简短、简单的XSLT解决方案,它实际上是一个单行XPath表达式。我的答案对您有用吗?考虑接受最好的答案吗?谢谢这个XPath技巧。如果可能的话,我只是在徘徊。这就是为什么我的答案略有不同(而且可能很傻)。如果你有时间和快乐,我想知道你对另一个的看法(或者回答)。再次感谢您分享您的知识。@empo:不客气。我希望您不要讨厌我对您的解决方案的评论…:)这不是一个“XSLT 1.0”解决方案——永远不要根据假定的XSLT 1.0转换在XSLT 2.0处理器上成功运行的事实得出任何结论。使用Saxon 6.5.x、MSXMLx、.NET XslCompiledTransform或任何其他与XSLT 1.0兼容的XSLT处理器进行尝试。然后纠正你的错误,或者更好,想出一个更好的解决方案。请注意:我并没有投你反对票。我相信我们参加SO是一次学习经历,我很高兴看到每个人都在成长。@Dimitre:我认为Saxon能够按照其中指定的版本处理xsl。我现在明白了1.0版警告的原因。我用Saxon 6尝试了我的解决方案,但失败了。如果我没有错的话,在XSLT1.0中,我不能在这样的节点集上使用
    xsl:value of
    。谢谢你的评论。
    <students>
        <student id="1234">
            <grade>HD</grade>
        </student>
        <student id="1234">
            <grade>C</grade>
        </student>
        <student id="1111">
            <grade>D</grade>
        </student>
    </students>
    
    15
    
    sum(document('mark.xml')/*/*
                         [@type = current()/*
                                         [@id='1234']/grade
                         ]
       )
    
    <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