我有一个程序,它解析三个不同的CrystalReport XML文件(类似的结构,但不同的后代级别),然后将值填充到一个类中。
以下是第一个例子:
public static List<VyplatnePasky> DeserialzieRozuctovanieMzdy(ref List<VyplatnePasky> _pasky, string sPath)
{
XDocument document = XDocument.Load(sPath);
var formattedAreaPairReport = from d in document.Descendants("FormattedReport".AddNamespace())
.Descendants("FormattedAreaPair".AddNamespace())
.Descendants("FormattedAreaPair".AddNamespace())
select d.Element("FormattedAreaPair".AddNamespace());
if (formattedAreaPairReport.Count() == 0)
{
//empty;
InsertErrorMessage("<formattedAreaPairReport> contains no data! No Data to parse from.", "DeserialzieRozuctovanieMzdy");
return _pasky;
}
//check if any sequence contains any matching elements
var GotElements = formattedAreaPairReport.Elements("FormattedAreaPair".AddNamespace()).Where(n=>n.Attribute("Level").Value == "3" && n.Attribute("Type").Value == "Group");
if (GotElements == null)
{
InsertErrorMessage("There are no matching elements under <formattedAreaPairReport>.", "DeserialzieRozuctovanieMzdy");
return _pasky;
}
foreach (XElement xElement in GotElements)
{
RozuctovanieMzda_Values(xElement, ref _pasky);
}
return _pasky;
}
这是第二个(第二个XML文档解析器):
public static List<VyplatnePasky> DeserializeVyplatnePasky(string sPath)
{
List<VyplatnePasky> _pasky = new List<VyplatnePasky>();
XDocument document = XDocument.Load(sPath);
var formattedAreaPairReport = from d in document.Descendants("FormattedReport".AddNamespace())
select d.Element("FormattedAreaPair".AddNamespace());
if (formattedAreaPairReport.Count() == 0)
{
//empty;
InsertErrorMessage("<formattedAreaPairReport> contains no data! No Data to parse from.", "DeserializeVyplatnePasky");
}
else
{
//sequence contains data
foreach (XElement xElement in formattedAreaPairReport.Elements("FormattedAreaPair".AddNamespace()))
{
VyplatnePasky _paska = new VyplatnePasky();
VyplatnePasky_Items(xElement, ref _paska);
_pasky.Add(_paska);
}
}
return _pasky;
}
从上面的代码中可以看出,所有三种XML解析方法看起来几乎相同;主要区别在于我在后代的深度。的 formattedAreaPairReport
我想做的是通过创建可以由所有三种方法使用的Generic void来使这些代码更专业和可重用。
我正在考虑创建多个Delegates,我将传递我的lambda命令,例如:
var formattedAreaPairReport = ProcessFirstLevel(from d in document.Descendants("FormattedReport".AddNamespace())
select d.Element("FormattedAreaPair".AddNamespace()));
然而,它只会成为一个很大的混乱空白。
问题是 - 这实际上是可行/值得做的吗?你能帮忙吗?
答案 0 :(得分:1)
您可以使用一些DRY技术稍微clean coding代码。尝试做这样的事情:
public static List<VyplatnePasky> DeserialzieRozuctovanieMzdy(ref List<VyplatnePasky> _pasky, string sPath)
{
var formattedAreaPairReport =
tryToGetItemsFromDocument
(
sPath,
document=>from d in document.Descendants("FormattedReport".AddNamespace())
.Descendants("FormattedAreaPair".AddNamespace())
.Descendants("FormattedAreaPair".AddNamespace())
select d.Element("FormattedAreaPair".AddNamespace()),
"DeserialzieRozuctovanieMzdy"
);
addItemsToVyplatnePasky(formattedAreaPairReport, ref _pasky);
return _pasky;
}
public static List<VyplatnePasky> DeserializeVyplatnePasky(string sPath)
{
List<VyplatnePasky> _pasky = new List<VyplatnePasky>();
var formattedAreaPairReport =
tryToGetItemsFromDocument
(
sPath,
document=>from d in document.Descendants("FormattedReport".AddNamespace())
select d.Element("FormattedAreaPair".AddNamespace()),
"DeserializeVyplatnePasky"
);
addItemsToVyplatnePasky2(formattedAreaPairReport, _pasky);
return _pasky;
}
private static void addItemsToVyplatnePasky(IEnumerable<XElement> formattedAreaPairReport, ref List<VyplatnePasky> _pasky)
{
if (formattedAreaPairReport.Count() > 0)
{
//check if any sequence contains any matching elements
var GotElements = formattedAreaPairReport.Elements("FormattedAreaPair".AddNamespace()).Where(n=>n.Attribute("Level").Value == "3" && n.Attribute("Type").Value == "Group");
if (GotElements == null)
{
InsertErrorMessage("There are no matching elements under <formattedAreaPairReport>.", "DeserialzieRozuctovanieMzdy");
return;
}
foreach (XElement xElement in GotElements)
{
RozuctovanieMzda_Values(xElement, ref _pasky);
}
}
}
private static void addItemsToVyplatnePasky2(IEnumerable<XElement> formattedAreaPairReport, List<VyplatnePasky> _pasky)
{
foreach (XElement xElement in formattedAreaPairReport.Elements("FormattedAreaPair".AddNamespace()))
{
VyplatnePasky _paska = new VyplatnePasky();
VyplatnePasky_Items(xElement, ref _paska);
_pasky.Add(_paska);
}
}
private static IEnumerable<XElement> tryToGetItemsFromDocument(string sPath, Func<XDocument, IEnumerable<XElement>> query, string name)
{
XDocument document = XDocument.Load(sPath);
var report = query(document);
if (report.Count() == 0)
{
//empty;
InsertErrorMessage("<formattedAreaPairReport> contains no data! No Data to parse from.", name);
}
return report;
}
基本上,您可以继续分解代码,然后查找要清理的重复习语。泛型可能会或可能不会作为清理的一部分发挥作用。此外,您可能希望为方法提供比我更好的名称,因为我不熟悉此代码中使用的本机语言。 : - )