我试图将一个XML文件转换为另一个XML文件,根据标记值对数据进行分组
我要转换以下XML文件:我试图将一个XML文件转换为另一个XML文件,根据标记值对数据进行分组,xml,sorting,xslt,grouping,Xml,Sorting,Xslt,Grouping,我要转换以下XML文件: <?xml version="1.0" encoding="UTF-8"?> <dataroot> <Op> <Where>AIX</Where> <Amount>24</Amount> </Op> <Op> <Where>LILLE</Where> <Amount>10</A
<?xml version="1.0" encoding="UTF-8"?>
<dataroot>
<Op>
<Where>AIX</Where>
<Amount>24</Amount>
</Op>
<Op>
<Where>LILLE</Where>
<Amount>10</Amount>
</Op>
<Op>
<Where>LILLE</Where>
<Amount>18</Amount>
</Op>
<Op>
<Where>AIX</Where>
<Amount>20</Amount>
</Op>
<Op>
<Where>LILLE</Where>
<Amount>12</Amount>
</Op>
</dataroot>
艾克斯
24
里尔
10
里尔
18
艾克斯
20
里尔
12
到
5.
84
艾克斯
2.
44
24
20
里尔
3.
40
10
18
12
也就是将为给定位置执行的操作分组在一起,计算它们的数量和每个位置的操作总量。我用sort做了一些尝试,但没有成功
我是个新手,我不知道怎么做
根据michael.hor257k建议,我尝试使用以下xsl代码创建分组,但仍然无法计算每个位置的操作计数(Nop)和LocAmount:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output encoding="UTF-8" method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="Ops-by-location" match="Op" use="Where" />
<xsl:template match="/">
<Document>
<Recap>
<Nop><xsl:value-of select="count(//Amount)"/></Nop>
<TotAmount><xsl:value-of select="sum(//Amount)"/></TotAmount>
</Recap>
<xsl:apply-templates/>
</Document>
</xsl:template>
<xsl:template match="/dataroot">
<xsl:apply-templates select="Op[generate-id(.) = generate-id(key('Ops-by-location', Where)[1])]"/>
</xsl:template>
<xsl:template match="Op">
<Where>
<xsl:value-of select="Where" />
<Nop>???</Nop>
<TotAmount>???</TotAmount>
<xsl:for-each select="key('Ops-by-location', Where)">
<Amount> <xsl:value-of select="Amount" /></Amount>
</xsl:for-each>
</Where>
</xsl:template>
</xsl:stylesheet>
???
???
试试这个
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string input =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<dataroot>" +
"<Op>" +
"<Where>AIX</Where>" +
"<Amount>24</Amount>" +
"</Op>" +
"<Op>" +
"<Where>LILLE</Where>" +
"<Amount>10</Amount>" +
"</Op>" +
"<Op>" +
"<Where>LILLE</Where>" +
"<Amount>18</Amount>" +
"</Op>" +
"<Op>" +
"<Where>AIX</Where>" +
"<Amount>20</Amount>" +
"</Op>" +
"<Op>" +
"<Where>LILLE</Where>" +
"<Amount>12</Amount>" +
"</Op>" +
"</dataroot>";
XDocument doc1 = XDocument.Parse(input);
var groups = doc1.Descendants("Op").GroupBy(x => x.Element("Where").Value).ToList();
int count = doc1.Descendants("Op").Count();
int total = doc1.Descendants("Amount").Select(x => (int)x).Sum();
XDocument doc2 = XDocument.Parse("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Document></Document>");
XElement document = doc2.Element("Document");
XElement recap = new XElement("Recap");
document.Add(recap);
recap.Add(new XElement("Nop", count));
recap.Add(new XElement("TotAmount", total));
foreach (var opGroup in groups.AsEnumerable())
{
XElement location = new XElement("Location");
document.Add(location);
location.Add(opGroup.Elements("Where").FirstOrDefault());
int groupCount = opGroup.Count();
int locAmount = opGroup.Descendants("Amount").Select(x => (int)x).Sum();
location.Add(new XElement("Nop", groupCount));
location.Add(new XElement("LocAmount", locAmount));
XElement ops = new XElement("Ops");
location.Add(ops);
foreach (var op in opGroup)
{
ops.Add(op.Element("Amount"));
}
}
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Xml;
使用System.Xml.Linq;
命名空间控制台应用程序1
{
班级计划
{
静态void Main(字符串[]参数)
{
字符串输入=
"" +
"" +
"" +
“AIX”+
"24" +
"" +
"" +
“里尔”+
"10" +
"" +
"" +
“里尔”+
"18" +
"" +
"" +
“AIX”+
"20" +
"" +
"" +
“里尔”+
"12" +
"" +
"";
XDocument doc1=XDocument.Parse(输入);
var groups=doc1.substands(“Op”).GroupBy(x=>x.Element(“Where”).Value).ToList();
int count=doc1.substands(“Op”).count();
int total=doc1.Sum(“金额”).Select(x=>(int)x.Sum();
XDocument doc2=XDocument.Parse(“”);
XElement文档=doc2.元素(“文档”);
XElement重述=新XElement(“重述”);
文件。添加(重述);
添加(新元素(“Nop”,计数));
加上(新项目(“总额”),总计);
foreach(组中的var opGroup.AsEnumerable())
{
XElement位置=新XElement(“位置”);
文件。添加(位置);
Add(opGroup.Elements(“Where”).FirstOrDefault());
int groupCount=opGroup.Count();
int locAmount=opGroup.substands(“Amount”).Select(x=>(int)x.Sum();
添加(新的元素(“Nop”,groupCount));
位置。添加(新元素(“LocAmount”,LocAmount));
XElement ops=新XElement(“ops”);
地点.增补(行动处);
foreach(opGroup中的var op)
{
运营增加(运营要素(“金额”);
}
}
}
}
}
我仍然无法计算操作计数(Nop)和LocAmount
对于每个位置
尝试:
或者,更有效一点:
<xsl:template match="Op">
<xsl:variable name="local-ops" select="key('Ops-by-location', Where)"/>
<Location>
<xsl:copy-of select="Where"/>
<Nop>
<xsl:value-of select="count($local-ops)"/>
</Nop>
<TotAmount>
<xsl:value-of select="sum($local-ops/Amount)"/>
</TotAmount>
<xsl:copy-of select="$local-ops/Amount"/>
</Location>
</xsl:template>
下面是一个使用Muenchian方法的XSLT 1.0解决方案:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" omit-xml-declaration="no" />
<xsl:key name="Where" match="/dataroot/Op/Where" use="text()" />
<xsl:template match="/">
<xsl:element name="Document">
<xsl:element name="Recap">
<xsl:for-each select="//dataroot">
<Nop><xsl:value-of select="count(*)"/></Nop>
<TotAmount><xsl:value-of select="sum(//Amount)"/></TotAmount>
</xsl:for-each>
</xsl:element>
<xsl:for-each select="/dataroot/Op/Where[generate-id()
= generate-id(key('Where',text())[1])]">
<xsl:element name="Location">
<Where><xsl:value-of select="."/></Where>
<Nop><xsl:value-of select="count(key('Where',text()))"/></Nop>
<LocAmount><xsl:value-of select="sum(key('Where',text())/../Amount)"/></LocAmount>
<xsl:element name="Ops">
<xsl:copy-of select="key('Where',text())/../Amount"/>
</xsl:element>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
搜索XSLT
和分组
——这可能是这里最常问的问题。请注意,XSLT1.0或2.0的答案不同。这是什么语言?这个问题被标记为XSLT.C#,但也可以在vb.net中完成。使用XML Linq。@Parfait正如我所说的,这个问题被标记为XSLT。我看不出“你的编程伙伴”喜欢什么有什么关系。
<xsl:template match="Op">
<xsl:variable name="local-ops" select="key('Ops-by-location', Where)"/>
<Location>
<xsl:copy-of select="Where"/>
<Nop>
<xsl:value-of select="count($local-ops)"/>
</Nop>
<TotAmount>
<xsl:value-of select="sum($local-ops/Amount)"/>
</TotAmount>
<xsl:copy-of select="$local-ops/Amount"/>
</Location>
</xsl:template>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" omit-xml-declaration="no" />
<xsl:key name="Where" match="/dataroot/Op/Where" use="text()" />
<xsl:template match="/">
<xsl:element name="Document">
<xsl:element name="Recap">
<xsl:for-each select="//dataroot">
<Nop><xsl:value-of select="count(*)"/></Nop>
<TotAmount><xsl:value-of select="sum(//Amount)"/></TotAmount>
</xsl:for-each>
</xsl:element>
<xsl:for-each select="/dataroot/Op/Where[generate-id()
= generate-id(key('Where',text())[1])]">
<xsl:element name="Location">
<Where><xsl:value-of select="."/></Where>
<Nop><xsl:value-of select="count(key('Where',text()))"/></Nop>
<LocAmount><xsl:value-of select="sum(key('Where',text())/../Amount)"/></LocAmount>
<xsl:element name="Ops">
<xsl:copy-of select="key('Where',text())/../Amount"/>
</xsl:element>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:template>
</xsl:stylesheet>