我有一个应用程序可以根据某些设置规则验证CSV文件。应用程序检查CVS中的某些“列/字段”是否标记为必需,其他则检查其强制状态是否基于另一个字段。例如。第2列对第5列进行了条件检查,这样如果第5列有值,则第2列也必须有值。
我已经使用VB和Python实现了这一点。问题是这个逻辑在应用程序中是硬编码的。我想要的是将此规则移动到一个XML中,其中应用程序将读取该XML并处理该文件。如果处理更改的规则 - 并且它们经常更改 - 则应用程序保持不变,只有XML更改。
以下是python中的两个示例规则:
示例一
current_column_data = 5 #data from the current position in the CSV
if validate_data_type(current_column_data, expected_data_type) == False:
return error_message
index_to_check_against = 10 #Column against which there is a "logical" test
text_to_check = get_text(index_to_check_against)
if validate_data_type(text_to_check, expected_data_type) == False:
return error_message
if current_column_data > 10: #This test could be checking String Vs String so have to keep in mind that to avoid errors since current column data could be a string value
if text_to_check <= 0:
return "Text to check should be greater than 0 if current column data is greater than 10 "
示例二
current_column_data = "Self Employed" #data from the current position in the CSV
if validate_data_type(current_column_data, expected_data_type) == False:
return error_message
index_to_check_against = 10 #Column against which there is a "logical" test
text_to_check = get_text(index_to_check_against)
if validate_data_type(text_to_check, expected_data_type) == False:
return error_message
if text_to_check == "A": #Here we expect if A is provided in the index to check, then current column should have a value hence we raise an error message
if len(current_column_data) = 0:
return "Current column is mandatory given that "A" is provided in Column_to_check""
注意:对于CSV中的每一列,我们已经知道了预期的数据类型,该字段的预期长度,是否为强制,可选或条件,以及其条件是否为其他列条件基于
现在我需要一些关于如何在XML中执行此操作的指导,并且应用程序读取XML并知道如何处理每个列。
有人在其他地方提出了以下示例,但我仍然无法理解这个概念。:
<check left="" right="9" operation="GTE" value="3" error_message="logical failure for something" />
#Meaning: Column 9 should be "GTE" i.e. Greater than or equal two value 3"
有没有不同的方法来实现这种逻辑,甚至是改善我在这里的方式?
建议和指示欢迎
答案 0 :(得分:2)
此概念称为域特定语言(DSL) - 您正在有效地创建用于验证CSV文件的迷你编程语言。您的DSL允许您明确简洁有效CSV文件的规则。
这个DSL可以用XML表示,或者另一种方法是在python中开发一个函数库。然后你的DSL可以表示为一个mini-python程序,它是这些函数的序列。这种方法被称为语言或“内部”DSL - 并且有一个好处,即您可以在您的语言中使用python的全部功能。
看着你的样品 - 你已经非常接近这个了。当我阅读它们时,它们几乎就像是CSV验证规则的英文描述。
不要觉得你必须遵循XML路线 - 在Python中保存所有内容没有任何问题
答案 1 :(得分:0)
您要解决的问题不一定与XML有关。好的,您可以使用XSD对XML进行验证,但这意味着您的数据需要是XML,并且我不确定您是否可以执行此操作以扩展“如果A&gt; 3,遵循规则适用”。
稍微不那么优雅,但可能比Ross答案更简单的方法,只是将规则集定义为 data 并具有特定的功能处理它们,这基本上是您的XML示例所做的,存储(即使用XML序列化数据---但您可以使用任何其他序列化格式,如JSON,YAML,INI甚至CSV(不建议使用它)。
因此,您可以专注于规则的数据模型。我将尝试使用XML(但不使用属性)来说明:
<cond name="some explanatory name">
<if><expr>...</expr>
<and>
<expr>
<left><column>9</column></left>
<op>ge</op>
<right>3</right>
</expr>
<expr>
<left><column>1</column></left>
<op>true</op>
<right></right>
</expr>
</and>
</cond>
然后,您可以将其加载到Python并遍历每行,并在适当的时候提出一个很好的解释异常。
编辑:您提到该文件可能需要是人类可写的。请注意,YAML是专为此而设计的。
类似(不一样,改为使其更好地说明语言)结构:
# comments, explanations...
conds:
- name: some explanatory name
# seen that? no quotes needed (unless you include some of
# quite limited set of special chars)
if:
expr:
# "..."
and:
expr:
left:
column: 9
op: ge
right: 3
expr:
left:
column: 1
op: true
- name: some other explanatory name
# i'm using alternative notation for columns below just to have
# them better indented (not sure about support in libs)
if:
expr:
# "..."
and:
expr:
left: { column: 9 }
op: ge
right: 3
expr:
left: { column: 1 }
op: true