作为我开发的一部分,我希望能够针对单个XSD文件验证整个文件夹的XML文件.PowerShell函数似乎是一个很好的候选者,因为我可以像这样管道一个文件列表:dir*.xml | Validate-Xml -Schema.\ MySchema.xsd
我已经考虑过在C#问题中从参考XSD验证一个Xml中移植C#代码,但我不知道如何在PowerShell中添加处理程序.
背景:
我们正在构建一个应用程序,允许我们的客户以预定义(即我们无法控制)的XML格式提供数据.XSD由第三方提供给我们,我们期望在我们处理它之前收到一个传递模式验证的XML文件.
问题:
我们提供的XSD包括默认和目标命名空间,这意味着如果客户提供的XML文件不包含命名空间,则验证将通过.我们显然不希望他们提供说他们通过但不应该提供的东西,但更大的问题是如果我找不到解决办法,我们需要对每个元素进行额外的检查. XML验证.
问题:
是否可以强制.NET执行验证并忽略提供的XML和XSD上的命名空间.即以某种方式"假设"命名空间被附加.
我到目前为止的解决方案:
示例Xml:
<?xml version="1.0"?>
<xsd:schema version='3.09' elementFormDefault='qualified' attributeFormDefault='unqualified' id='blah' targetNamespace='urn:schemas-blah.com:blahExample' xmlns='urn:blah:blahExample' xmlns:xsd='http://www.w3.org/2001/XMLSchema'>
...
</xsd:schema>
Run Code Online (Sandbox Code Playgroud)
与命名空间不同
<?xml version="1.0" encoding="UTF-8" ?>
<root xmlns="urn:myCompany.com:blahExample1" attr1="2001-03-03" attr2="google" >
...
</root>
Run Code Online (Sandbox Code Playgroud)
没有命名空间.
<?xml version="1.0" encoding="UTF-8" ?>
<root attr1="2001-03-03" attr2="google" >
...
</root>
Run Code Online (Sandbox Code Playgroud) 我使用Visual StudioXML工具创建了XSD.我使用以下C#代码来验证XML并面临此错误.
错误
该元素未声明为" http://www.w3.org/2000/09/xmldsig#:Signature ".
所以我的问题是如何解决它,因为在编辑模式下XML有效100%?
谢谢!
C#
private void buttonValidateXML_Click(object sender, EventArgs e)
{
try
{
bool result = IsValidXml2(textBoxSignedXML.Text, textBoxXSDFile.Text, "");
rtbValidationResult.Text = result.ToString();
}
catch (Exception ex)
{
rtbValidationResult.Text = ex.Message;
}
}
public static bool IsValidXml2(string xmlFilePath, string xsdFilePath, string namespaceName)
{
var xdoc = XDocument.Load(xmlFilePath);
var schemas = new XmlSchemaSet();
schemas.Add(namespaceName, xsdFilePath);
bool result = true;
xdoc.Validate(schemas, (sender, e) =>
{
result = false;
});
return result;
}
Run Code Online (Sandbox Code Playgroud)
XML
<?xml version="1.0" encoding="utf-8"?>
<Envelope version="1"> …Run Code Online (Sandbox Code Playgroud) 我知道我可以使用如下所示的回调方法对模式验证xml,但有没有一种方法可以同步而不是事件驱动?
我想到的一种方法是设置一个类成员布尔标志IsValidated = false然后
调用xml.Validate(ValidationEventHandler).一旦完成,事件处理程序将设置IsValidated = true.同时,执行循环检查,直到标志设置为true然后继续.
这是针对.Net 3.5的.
public bool ValidateSchema(string xmlPath, string xsdPath)
{
XmlDocument xml = new XmlDocument();
xml.Load(xmlPath);
xml.Schemas.Add(null, xsdPath);
xml.Validate(ValidationEventHandler);
}
Run Code Online (Sandbox Code Playgroud)
好的,我已经完成了测试,看起来xml.validate实际上等待,直到回执完成才执行新代码.
在下面的示例中,MessageBox.Show("After Validate"); 总是在执行myValidationEventHandler之后发生.
我还通过代码来验证这一点.
所以我想这使我的问题成为一个问题.
// load etc.
...
xmlValidate(myValidationEventHandler);
MessageBox.Show("After Validate");
private void myValidationEventHandler(object sender, ValidationEventArgs e)
{
for (double i = 0; i < 100000; i++)
{
textBox1.Text = i.ToString();
Application.DoEvents();
}
// do stuff with e
}
Run Code Online (Sandbox Code Playgroud) 我希望用户能够将数据导出为XML文件.当然,我希望他们以后能够导入相同的XML文件,但是他们总是可以更改它,或者它可能是不同的XML文件.
所以我想验证XML文件以检查它是否采用我期望的格式.所以我想我需要像模式一样来检查它必须通过代码.
所以,如果我期待
<Root>
<Something>
<SomethingElse> </SomethingElse>
</Something>
</Root>
Run Code Online (Sandbox Code Playgroud)
我不希望其他格式在文件中,而不是我期望的格式.
另外我如何验证字段?就像说我要求标签之间必须有一些文字.如果为空,则文件无效.
那怎么能这样呢?
编辑
我决定使用XML序列化,所以我知道如果格式错误并忽略不起作用的东西,它将通过异常.但是我不确定我是否应该通过它和C#来验证每个记录,或者我应该尝试使用xml架构来完成它.
如果我想通过xml序列化的xml架构来实现它将如何工作?就像我首先做的事情,就像我在回复中看到的那样,然后将其序列化?或者我该怎么做?
我需要创建一个接受xml的.NET Web服务,使用它来查询数据库,然后返回xml.我已经获得了请求和响应的xsd文件.有人能指出我从哪里开始的正确方向或一个例子?
我之前没有使用过WCF,所以我更喜欢用一个简单的asmx文件来做这件事.我知道如何从数据库中获取数据,因此我丢失了xml和web服务位.
我试过谷歌搜索一段时间,但不知道从哪里开始.谢谢.