我有一个类似以下的XML结构:
<Root>
<Base>
<Greeting>Base Hello!</Greeting>
<SpecialMessage>Base Special Message</SpecialMessage>
<Products>
<Product id="001">
<Greeting>Base 001 Hello!</Greeting>
</Product>
</Products>
</Base>
<Buy>
<Greeting>Buy Hello!</Greeting>
<SpecialMessage>Buy Special Message</SpecialMessage>
<Products>
<Product id="001">
<Greeting>Buy 001 Hello!</Greeting>
</Product>
</Products>
</Buy>
<Rent>
<Greeting>Rent Hello</Greeting>
</Rent>
</Root>
Base,Buy和Rent节点将始终存在,但其中的节点可能会也可能不会。在运行时,我将确定这是购买还是租赁方案。我也可能有也可能没有产品ID。
例如,如果是购买场景且产品ID为“001”,我将收到“Buy 001 Hello”消息。但是,如果因任何原因导致“购买”部分中的“产品”部分丢失,我将返回“Base 001 Hello”。
第二个例子是如果我想获得一个Rent场景的SpecialMessage。由于Rent部分中没有SpecialMessage节点,我将返回“Base Special Message”
我使用Greeting作为产品001的购买方案中的示例,汇总了这样的XPath列表:
此刻,我从列表的顶部开始,运行XPath,如果找到结果则返回结果,其他明智地转到下一个XPath,依此类推:
string result;
result = RunXPath(xpaths["Level1"], document);
if (!String.IsNullOrEmpty(result))
return result;
result = RunXPath(xpaths["Level2"], document);
if (!String.IsNullOrEmpty(result))
return result;
result = RunXPath(xpaths["Level3"], document);
if (!String.IsNullOrEmpty(result))
return result;
result = RunXPath(xpaths["Level4"], document);
if (!String.IsNullOrEmpty(result))
return result;
return String.Empty;
虽然它有效,但看起来很尴尬和粗略。在可读性方面是否有更好的方法?
答案 0 :(得分:0)
一种选择是创建路径集合,并迭代它:
string[] paths = {"Level1", "Level2", "Level3", "Level4"};
foreach(string path in paths)
{
result = RunXPath(xpaths[path], document);
if (!String.IsNullOrEmpty(result))
return result;
}
return "";
通常,如果您发现自己编写重复代码,则应考虑使用循环或方法(或两者兼而有之!) 另外,尽量不要对不同的东西使用相同的变量。寻找有意义的名称 - 它将有助于提高可读性,并帮助检测错误。这在你的传统中不那么冒犯,但足够重要。考虑:
result = RunXPath(xpaths["/document/my:things/rooms[0]/floor"], document);
Print(result);
result = RunXPath(xpaths["/document/my:things/roomate/phone/mobile"], document);
Print(result);
我最近不得不像这样调试代码,并将其重构为:
string floor = RunXPath(xpaths["/document/my:things/rooms[0]/floor"], document);
Print(floor);
string friendMobilePhone = RunXPath(xpaths["/document/my:things/roomate/phone/mobile"], document);
Print(friendMobilePhone);