长篇故事(详见下文)简介,是否有人知道我可以构建查询以将重复数据返回到已知的xml格式,因此每个节点和子元素会针对给定条件单独返回?
编辑:我想我的问题归结为:我如何查询重复数据,并获得一组条目,直到下一次出现重复?
UNB
UNH
MID
DAN
UNS
UNT
UNH
MID
DAN
UNS
UNT
UNH
MID
DAN
UNS
UNT
UNH
MID
DAN
UNS
UNT
UNH
MID
DAN
UNS
UNT
因此,在这种情况下,知道某些段重复,我如何编写一个返回UNH-UNT的查询,分组为:
UNH
MID
DAN
UNS
UNT
完整详情
我需要将一个通用edi(EDIFACT)写入xml映射器。由于xml是结构化的,并且我已经设计了应用程序来导入xml文件,因此使用实体框架提取并存储文件的结构。
Xml结构存储为名为Translation的自引用实体。转换包含xml节点,它映射到的Edifact段名称以及从中提取值的复合和元素的位置。翻译还将自身引用为父/子关联(以镜像xml结构)。 UI自动将每个节点中的内容与段,复合和元素位置匹配。
我遇到的问题是如何将重复数据分成适当的重复父节点:
我通过提取没有父母的翻译来构建这个,然后递归地沿着树走下去:
var rootTrans = (from t in Translations
where t.ParentID==null
select t).ToList();
//(msg is the EDI transmission with a collection of segments-each segment contains composites, each composite contains elements with the actual data eg- )
XElement root = new XElement(Tag.Replace(" ", ""));
foreach (var item in rootTrans)
{
item.AddContentRecursive(root, msg);
}
var doc = new XDocument(root);
// AddContentRecursive
public void AddContentRecursive(XElement element, Transmission msg)
{
// Find matching segments for this tag
var segNodes = (from s in msg.Segments
where s.Value == Name
select GetElementValue(s, Positions)).DefaultIfEmpty(null);
// simply add the matching nodes to the parent element
if (Children.Count == 0)
{
var nodes = (from t in segNodes
select new XElement(Tag, t));
element.Add(nodes);
}
else
{
var aNode = new XElement(Tag);
element.Add(aNode);
foreach (var chil in Children.OrderBy(c => c.DocumentOrder))
{
chil.AddContentRecursive(aNode, msg);
}
}
}
EDI文件由客户控制,并按照他们自己的模式,从下面的例子中UNH段是一个消息头,并将重复直到UNT。 UNH的翻译实体有一个名为tag(MessageHeader)的属性和一个名为Name(UNH)的属性:
UNH + ORDERR319952 + ORDERR:1 :: OD'ENG MID + ORDERR319952 + 120818'
DAN +:建议注意+ TGBGU649'
MSD + CR'
SDT + 0831824'
BDT + PIPUK +++++ RB'
ART ++ 46210JD000 ::::: PIPE WORK,RH'
DLV ++ 2160:45'
DTP + 120823:1700'
PIN + 21'
TCO +:BLB + 24 + 90'
CSG + 0831824 + F01-XJ10'
UNS + S'
UNT + 14 + ORDERR319952'
UNH + ORDERR340246 + ORDERR:1 :: OD'
MID + ORDERR340246 + 120818'
DAN +:建议注意+ RRHBU636'
MSD + CR'
SDT + 0831824'
BDT + PIPUK +++++ RB'
ART ++ 46210JD005 ::::: PIPE WORK,LH'
DLV ++ 2160:45'
DTP + 120823:1700'
PIN + 21'
TCO +:BLB + 24 + 90'
CSG + 0831824 + F01-XJ10'
UNS + S'
UNT + 14 + ORDERR340246'
UNH + ORDERR340247 + ORDERR:1 :: OD'ENG MID + ORDERR340247 + 120818'
DAN +:建议注意+ RRHBU641'
MSD + CR'
SDT + 0831824'
BDT + PIPUK +++++ RB'
ART ++ 46210JD600 ::::: PIPE WORK,RH'
DLV ++ 4200:45'
DTP + 120823:1700'
PIN + 21'
TCO +:BAC4325 + 28 + 150'
CSG + 0831824 + F01-XJ10'
UNS + S'
UNT + 14 + ORDERR340247'
我尝试了不同的查询,递归,循环组合,我知道我缺少一些基本的东西,我在砖墙领域。有人遇到过这种问题吗?任何有关塑造查询的建议,将不胜感激。 感谢
答案 0 :(得分:0)
经过几个小时的单独圈赛,与同事进行了10分钟的讨论,产生了可行的解决方案。这是让段确定流量(而不是我想要的映射)。
EDI数据是连续的,并且通过扩展,这些段也是顺序的,因此它需要逐步执行每个段,与其转换或映射配对,并使用占位符来创建和嵌套XML节点。
不是最漂亮的(可能有更好的方法做同样的事情),但它始终有效:
// Get a collection of segments and maps
var SegsAndMaps = (from s in msg.Segments
join t in Maps on s.Value equals t.Name
orderby s.Id
select new { Segment = s, Map = t }).ToList();
// Set the placeholders
currentNode = null;
currentParent = null;
for (int i = 0; i < SegsAndMaps.Count; i++)
{
var item = SegsAndMaps[i];
// Separate the properties from anonymous type for clarity
var aMap = item.Map;
var aSegment = item.Segment;
var xml = aSegment.Xml(aMap);
// If this map shares the same parent
if (aMap.Parent == currentParent)
{
// Add the xml to the current node
currentNode.Add(xml);
}
else
{
// Change of parent, walk up the tree to get the right parent
var trans = aMap;
while (currentParent != aMap.Parent)
{
trans = trans.Parent;
currentParent = trans.Parent;
}
// Walk up the xml tree to find the parent tag to add this xml to
currentNode = currentNode.Ancestors().DescendantsAndSelf(currentParent.Tag).FirstOrDefault();
currentNode.Add(xml);
}
if (aMap.Children.Count > 0)
{
// If this map has child mappings, then update current parent to this, and its xml as the current node
currentNode = xml;
currentParent = aMap;
}
}
var doc = new XDocument(currentNode);