我在磁盘上的本地文件中有一个XSD架构。该XSD可以随时更新,也可以更改。因此它是动态的,我无法抓住它或留在某个地方。
我的目标是能够获得所有可能的XML元素的列表,以及其相应的祖先路径,并在控制台中打印出来。示例:
Desired Console output:
Html
Head - Html
Style - Head - Html
Body - Html
div - Body - Html
p - div - Body - Html
span - div - Body - Html
strong - div - Body - Html
注意:我不是使用Actual Html DOM,而是用它来解释层次结构。
简单的解决方案(我希望可以...)解析XSD并过滤具有 name =“ [anyHtmlTag]” 的元素的所有实例能够获取所有可能元素的列表,但无法获取其父对象的路径。我的XSD使用的是指位于XSD中更深处的一种类型,这是一个简短的示例:
问题是因为我处于顺序,因此在这种情况下,“ span”,“ p”或“ strong”属性无法看到其父级“ div”。< / p>
Actual result that is not desired
Html
Head - Html
Style - Head - Html
Body - Html
div - Body - Html
p
span
strong
之所以看不到它,是因为我正在解析(在C#中)XSD模式,就好像它是XML文档一样。
通过这种方式,我一直希望随着层次的深入,它将始终看到其祖先。
所以我的代码在这里工作得很好,直到在XSD中命中了 Sequence reference (序列参考),并获得了元素,但未能获得其祖先。
C#代码示例
public List<string> GetAllXmlPaths(out List<ValidationResult> errors)
{
errors = new List<ValidationResult>();
List<string> foundPaths = new List<string>();
string path = @"C:\temp\XSD.xsd"; // this is dynamic
XmlTextReader reader = new XmlTextReader(path);
XmlSchema myschema = XmlSchema.Read(reader, ValidationCallback);
StringWriter sw = new StringWriter();
myschema.Write(sw);
string XSD = sw.ToString();
var xs = XNamespace.Get("http://www.w3.org/2001/XMLSchema");
var doc = XDocument.Parse(XSD);
foreach (var element in doc.Descendants(xs + "element"))
{
// check ancestors
string pathToTheTop = "";
if (element.Ancestors(xs + "element").Any())
{
foreach (var p in element.Ancestors(xs + "element"))
{
pathToTheTop = pathToTheTop+ "\\" + p.Attribute("name").Value;
}
}
foundPaths.Add(element.Attribute("name").Value + ":" + pathToTheTop);
Console.WriteLine(element.Attribute("name").Value + ":" + pathToTheTop);
}
return foundPaths;
}
为什么要创建XML?到目前为止,我的解决方案是使用示例数据(与什么数据无关)以编程方式创建XML,但必须生成所有可能的XML。 XSD提供的路径。这样,所有祖先都会出现,并且我可以轻松解析所有层次结构。
VS具有内置功能,允许您右键单击并通过 XMLSchemaExplorer 从XSD生成示例XML。这里的更多信息:Generate a test XML from XML Schema programmatically因此,我需要完全相同的功能,但是要以编程方式(在我仍处于运行时)进行。