如何在 c# 中分析带有属性作为条件的复杂 XML
本文关键字:属性 条件 XML 复杂 | 更新日期: 2023-09-27 18:34:23
我是XML解析的初学者。我尝试了许多示例来读取此 XML 并仅解析需要的内容。我想知道哪个是更好的选择,是XML还是Linq。
这是我的 XML:
<?xml version="1.0" encoding="UTF-8"?>
<AcSmDatabase clsid="g2162C6B6-0CE4-40E8-912B-46F59DFDF826" ID="g9FF6C26D-885D-4C19-8B8C-69C43567DDED">
<AcSmProp propname="DbFingerPrint" vt="8">gB81BEEBE-7D91-4E80-BC96-A4E7FF6EDCF7</AcSmProp>
<AcSmSheetSet clsid="gB20534F2-0978-418C-8D14-2E6928A077ED" ID="g5842FAA3-9006-470A-97D6-58BA675533B0" propname="SheetSet" vt="13">
<AcSmProp propname="Name" vt="8">TestSSet</AcSmProp>
<AcSmFileReference clsid="g6BF87AE7-1BEC-4BDB-98BB-5B91F7772793" ID="g50C8E86D-E25F-4EFE-966F-E676C90C1551" propname="NewSheetLocation" vt="13">
<AcSmProp propname="FileName" vt="8">D:'Thyagu'AutoCAD14</AcSmProp>
<AcSmProp propname="Relative_FileName" vt="8">.</AcSmProp>
</AcSmFileReference>
<AcSmProjectPointLocations clsid="gE40EA246-BAB4-4907-81A5-511EA30C16FD" ID="g6F754DE4-5BC0-4159-A068-A961CFEBE56C" propname="ProjectPointLocations" vt="13" />
<AcSmProp propname="PromptForDwt" vt="2">-1</AcSmProp>
<AcSmPublishOptions clsid="gF57F96E7-0F16-4DC9-8F09-52F7BB389AB6" ID="g0510F544-063F-4BC7-B063-557E498985EF" propname="PublishOptions" vt="13">
<AcSmProp propname="DwfType" vt="2">-1</AcSmProp>
<AcSmProp propname="EplotFormat" vt="3">2</AcSmProp>
<AcSmProp propname="PromptForName" vt="2">-1</AcSmProp>
</AcSmPublishOptions>
<AcSmResources clsid="g3F0FAF10-09DE-4EBA-AED1-C4E4D6FECF5D" ID="gB7FF57F8-A338-4933-B166-CA7D92FE0F30" propname="Resources" vt="13" />
<AcSmSheetSelSets clsid="g444780B8-6527-43A8-8DC4-FAB41B7E48BB" ID="g29ED9C5D-7A76-470C-9C03-6DA6B6EEE8B5" propname="SheetSelSets" vt="13" />
<AcSmViewCategories clsid="g021730DF-5BEA-48E9-BC7A-35087A674FD0" ID="g2497A15A-A6EA-452C-9699-156310CA84B1" propname="ViewCategories" vt="13">
<AcSmViewCategory clsid="g4AEA81ED-C24F-477B-A534-EA69220A276A" ID="g120BB674-4D16-49E4-9288-05D67A447621">
<AcSmCalloutBlockReferences clsid="g67C52FE4-0A6B-4C82-A4CC-5E68537747B0" ID="g82F94574-0931-48A0-8C3A-27DE3FE3C9D3" propname="CalloutBlocks" vt="13" />
</AcSmViewCategory>
</AcSmViewCategories>
<AcSmSubset clsid="g076D548F-B0F5-4FE1-B35D-7F7B73B8D322" ID="g6843B16C-93BA-46AD-B965-3E7277F61AFB">
<AcSmProp propname="Desc" vt="8">New subset added</AcSmProp>
<AcSmProp propname="Name" vt="8">SubsetOne</AcSmProp>
<AcSmFileReference clsid="g6BF87AE7-1BEC-4BDB-98BB-5B91F7772793" ID="gE52BEABE-8B71-4BA7-9D1B-210411A6B2B7" propname="NewSheetLocation" vt="13">
<AcSmProp propname="FileName" vt="8">D:'Thyagu'AutoCAD14</AcSmProp>
<AcSmProp propname="Relative_FileName" vt="8">.</AcSmProp>
</AcSmFileReference>
<AcSmProp propname="PromptForDwt" vt="2">-1</AcSmProp>
<AcSmSheet clsid="g16A07941-BC15-4D48-A880-9D5A211D5065" ID="g1FC4F6B2-9619-4AA7-84FD-F4AFA750CC73">
<AcSmAcDbLayoutReference clsid="g94910E94-4FCA-427C-B6ED-2EC9E1C900C7" ID="g8F448CF5-BB6A-4952-8974-4DFED14A6F2F" propname="Layout" vt="13">
<AcSmProp propname="AcDbHandle" vt="8">1E</AcSmProp>
<AcSmProp propname="FileName" vt="8">D:'Thyagu'AutoCAD14'1 layoutrenamesheet.dwg</AcSmProp>
<AcSmProp propname="Name" vt="8">layoutOne</AcSmProp>
<AcSmProp propname="Relative_FileName" vt="8">.'1 layoutrenamesheet.dwg</AcSmProp>
</AcSmAcDbLayoutReference>
<AcSmProp propname="Number" vt="8">1</AcSmProp>
<AcSmSheetViews clsid="gF40F931B-64BC-4B90-9FC8-A11A77D6815B" ID="g825D8B24-6B23-453D-96A4-93905CEE9B7E" propname="SheetViews" vt="13" />
<AcSmProp propname="Title" vt="8">layoutrenamesheet</AcSmProp>
<AcSmProp propname="Desc" vt="8"> </AcSmProp>
<AcSmProp propname="RevisionNumber" vt="8"> </AcSmProp>
<AcSmProp propname="RevisionDate" vt="8"> </AcSmProp>
<AcSmProp propname="IssuePurpose" vt="8"> </AcSmProp>
<AcSmProp propname="Category" vt="8"> </AcSmProp>
</AcSmSheet>
</AcSmSubset>
<AcSmSubset clsid="g076D548F-B0F5-4FE1-B35D-7F7B73B8D322" ID="gCFD0B39D-FF06-4C0C-913F-8BC9E2122BCC">
<AcSmProp propname="Desc" vt="8">New subset added</AcSmProp>
<AcSmProp propname="Name" vt="8">SubsetTwo</AcSmProp>
<AcSmFileReference clsid="g6BF87AE7-1BEC-4BDB-98BB-5B91F7772793" ID="gA9769EC1-D268-4F19-B8D3-3B30E394A594" propname="NewSheetLocation" vt="13">
<AcSmProp propname="FileName" vt="8">D:'Thyagu'AutoCAD14</AcSmProp>
<AcSmProp propname="Relative_FileName" vt="8">.</AcSmProp>
</AcSmFileReference>
<AcSmProp propname="PromptForDwt" vt="2">-1</AcSmProp>
</AcSmSubset>
<AcSmProp propname="Desc" vt="8">New subset added</AcSmProp>
<AcSmProp propname="Name" vt="8">SubsetThree</AcSmProp>
<AcSmFileReference clsid="g6BF87AE7-1BEC-4BDB-98BB-5B91F7772793" ID="g3EFE83CC-A0D0-45FC-832C-E4CF1ACAACAD" propname="NewSheetLocation" vt="13">
<AcSmProp propname="FileName" vt="8">D:'Thyagu'AutoCAD14</AcSmProp>
<AcSmProp propname="Relative_FileName" vt="8">.</AcSmProp>
</AcSmFileReference>
<AcSmProp propname="PromptForDwt" vt="2">-1</AcSmProp>
<AcSmSheet clsid="g16A07941-BC15-4D48-A880-9D5A211D5065" ID="gD5BD538E-95F5-4F8C-B240-75A7181273B3">
<AcSmAcDbLayoutReference clsid="g94910E94-4FCA-427C-B6ED-2EC9E1C900C7" ID="gC30A57FC-2D0B-4436-AA00-12470B432686" propname="Layout" vt="13">
<AcSmProp propname="AcDbHandle" vt="8">1E</AcSmProp>
<AcSmProp propname="FileName" vt="8">D:'Thyagu'AutoCAD14'3 sheet1.dwg</AcSmProp>
<AcSmProp propname="Name" vt="8">layoutThree</AcSmProp>
<AcSmProp propname="Relative_FileName" vt="8">.'3 sheet1.dwg</AcSmProp>
</AcSmAcDbLayoutReference>
<AcSmProp propname="Number" vt="8">3</AcSmProp>
<AcSmSheetViews clsid="gF40F931B-64BC-4B90-9FC8-A11A77D6815B" ID="g704A6223-E755-4662-B108-843AB35BF838" propname="SheetViews" vt="13" />
<AcSmProp propname="Title" vt="8">sheet1</AcSmProp>
<AcSmProp propname="Desc" vt="8"> </AcSmProp>
<AcSmProp propname="RevisionNumber" vt="8"> </AcSmProp>
<AcSmProp propname="RevisionDate" vt="8"> </AcSmProp>
<AcSmProp propname="IssuePurpose" vt="8"> </AcSmProp>
<AcSmProp propname="Category" vt="8"> </AcSmProp>
</AcSmSheet>
<AcSmSheet clsid="g16A07941-BC15-4D48-A880-9D5A211D5065" ID="gE88F3C2A-92EE-4CF9-BBE8-F2ED4ED2433E">
<AcSmAcDbLayoutReference clsid="g94910E94-4FCA-427C-B6ED-2EC9E1C900C7" ID="g46C592DC-86D8-4173-974C-36633B209CBB" propname="Layout" vt="13">
<AcSmProp propname="AcDbHandle" vt="8">1E</AcSmProp>
<AcSmProp propname="FileName" vt="8">D:'Thyagu'AutoCAD14'4 sheet2.dwg</AcSmProp>
<AcSmProp propname="Name" vt="8">layoutFour</AcSmProp>
<AcSmProp propname="Relative_FileName" vt="8">.'4 sheet2.dwg</AcSmProp>
</AcSmAcDbLayoutReference>
<AcSmProp propname="Number" vt="8">4</AcSmProp>
<AcSmSheetViews clsid="gF40F931B-64BC-4B90-9FC8-A11A77D6815B" ID="g9F4A3151-F82D-4D86-9A76-F405001A2383" propname="SheetViews" vt="13" />
<AcSmProp propname="Title" vt="8">sheet2</AcSmProp>
<AcSmProp propname="IssuePurpose" vt="8">koluppu</AcSmProp>
<AcSmProp propname="Desc" vt="8"> </AcSmProp>
<AcSmProp propname="RevisionNumber" vt="8"> </AcSmProp>
<AcSmProp propname="RevisionDate" vt="8"> </AcSmProp>
<AcSmProp propname="Category" vt="8"> </AcSmProp>
</AcSmSheet>
<AcSmSheet clsid="g16A07941-BC15-4D48-A880-9D5A211D5065" ID="gD0451C82-D493-43CC-A6CA-87642FA96DA9">
<AcSmAcDbLayoutReference clsid="g94910E94-4FCA-427C-B6ED-2EC9E1C900C7" ID="gED7DCAB4-45BC-43C8-A226-DF3842FB9B8D" propname="Layout" vt="13">
<AcSmProp propname="AcDbHandle" vt="8">1E</AcSmProp>
<AcSmProp propname="FileName" vt="8">D:'Thyagu'AutoCAD14'5 sheet3.dwg</AcSmProp>
<AcSmProp propname="Name" vt="8">layoutFive</AcSmProp>
<AcSmProp propname="Relative_FileName" vt="8">.'5 sheet3.dwg</AcSmProp>
</AcSmAcDbLayoutReference>
<AcSmProp propname="Number" vt="8">5</AcSmProp>
<AcSmSheetViews clsid="gF40F931B-64BC-4B90-9FC8-A11A77D6815B" ID="gD211C7F5-81FE-4B46-8083-218D322165E4" propname="SheetViews" vt="13" />
<AcSmProp propname="Title" vt="8">sheet3</AcSmProp>
<AcSmProp propname="Desc" vt="8"> </AcSmProp>
<AcSmProp propname="RevisionNumber" vt="8"> </AcSmProp>
<AcSmProp propname="RevisionDate" vt="8"> </AcSmProp>
<AcSmProp propname="IssuePurpose" vt="8"> </AcSmProp>
<AcSmProp propname="Category" vt="8"> </AcSmProp>
</AcSmSheet>
</AcSmSubset>
<AcSmSheet clsid="g16A07941-BC15-4D48-A880-9D5A211D5065" ID="g611F8282-3FAA-42B5-8CBC-614DD0713570">
<AcSmAcDbLayoutReference clsid="g94910E94-4FCA-427C-B6ED-2EC9E1C900C7" ID="g90BAA810-F2F2-4CED-82C4-89E86943CFBB" propname="Layout" vt="13">
<AcSmProp propname="AcDbHandle" vt="8">1E</AcSmProp>
<AcSmProp propname="FileName" vt="8">D:'Thyagu'AutoCAD14'6 t1.dwg</AcSmProp>
<AcSmProp propname="Name" vt="8">layoutSix</AcSmProp>
<AcSmProp propname="Relative_FileName" vt="8">.'6 t1.dwg</AcSmProp>
</AcSmAcDbLayoutReference>
<AcSmProp propname="Number" vt="8">6</AcSmProp>
<AcSmSheetViews clsid="gF40F931B-64BC-4B90-9FC8-A11A77D6815B" ID="g99805F55-4F5C-4121-A2D3-F94F5549B668" propname="SheetViews" vt="13" />
<AcSmProp propname="Title" vt="8">t1</AcSmProp>
<AcSmProp propname="Desc" vt="8"> </AcSmProp>
<AcSmProp propname="RevisionNumber" vt="8"> </AcSmProp>
<AcSmProp propname="RevisionDate" vt="8"> </AcSmProp>
<AcSmProp propname="IssuePurpose" vt="8"> </AcSmProp>
<AcSmProp propname="Category" vt="8"> </AcSmProp>
</AcSmSheet>
</AcSmSheetSet>
</AcSmDatabase>
此 XML 的结构:
用词来说:图纸集是一个项目,它可以包含任何没有文件夹(子集(和图纸。
文件夹(子集(可以包含任何文件夹(子集(和工作表。
每个工作表都应该有一个名为布局的属性。
我想单独获取布局属性。
我需要的输出:
布局位置., 布局名称., 布局标题.,
它将采用任何设置格式(列表,数据表等(。
"D:''Thyagu''AutoCAD14''1 layoutrenamesheet.dwg"., layoutOne., layoutrenamesheet.,
"D:''Thyagu''AutoCAD14''6 t1.dwg"., layoutSix., t1.,
我为此进行了很长时间的研发,但仍然没有得到解决方案。
我使用的 C# 代码:
XmlNodeList xmlSubSetList = Doc.SelectNodes("AcSmDatabase/AcSmSheetSet/AcSmSubset");
foreach (XmlNode node in xmlSubSetList)
{
XmlNode xmlFolder = node;
XmlNodeList xmlSheets = xmlFolder.SelectNodes("AcSmSheet");
foreach (XmlNode xmlSheetProp in xmlSheets) //{ }
{
XmlNodeList xmlEle = xmlSheetProp.SelectNodes("AcSmAcDbLayoutReference");
foreach (XmlNode xmlLastNode in xmlEle)
{
XmlNodeList xmlFinalLoop = xmlLastNode.SelectNodes(".//AcSmProp");
foreach (XmlNode xmlEnd in xmlFinalLoop)
{
if (xmlEnd.Attributes["propname"].Value == "FileName")
{
string strFileLocation = xmlEnd.InnerText.ToString();
XmlNode xmlParentParentNode = xmlEnd.ParentNode.ParentNode;
XmlNodeList xmlLayoutTitleLoop = xmlParentParentNode.SelectNodes(".//AcSmProp");
foreach (XmlNode xmlTitle in xmlLayoutTitleLoop)
{
if (xmlTitle.Attributes["propname"].Value == "Title")
{
string strTitle = xmlTitle.InnerText.ToString();
ListOfSheetNames += strTitle + "-";
}
}
}
}
}
}
}
但是"AcSmSheet"标签的位置不是标准的。
它将根据他在创建时描述的最终用户格式动态变化。
唯一的问题是表格总是以"AcSmSheet"标签开头。这样我就无法访问任何子文件夹子文件夹下的工作表。
谢谢
历 XML 文档并对其执行复杂查询的最简单方法是 Linq-to-XML
。
使用此语句:
XDocument doc = XDocument.Load(@"somePath'myXMLFile.xml");
可以将整个 XML 树结构加载到XDocument
中。
然后,可以使用Descendants
方法获取 XML 文档中包含的所有AcSmSheet
元素,而不管它们的位置如何。有了这个,您可以执行以下查询以返回所需的结果集:
var results = from sheet in xdoc.Descendants("AcSmSheet")
select new
{
LayoutLocation = sheet.Descendants("AcSmProp")
.Where(t => t.Attribute("propname")
.Value == "FileName")
.First().Value,
LayoutName = sheet.Descendants("AcSmProp")
.Where(t => t.Attribute("propname")
.Value == "Name")
.First().Value,
LayoutTitle = sheet.Descendants("AcSmProp")
.Where(t => t.Attribute("propname")
.Value == "Title")
.First().Value
};
使用 OP 中提供的 XML 摘录,上述查询将产生以下结果:
[0] = { LayoutLocation = "D:''Thyagu''AutoCAD14''1 layoutrenamesheet.dwg", LayoutName = "layoutOne", LayoutTitle = "layoutrenamesheet" }
[1] = { LayoutLocation = "D:''Thyagu''AutoCAD14''3 sheet1.dwg", LayoutName = "layoutThree", LayoutTitle = "sheet1" }
[2] = { LayoutLocation = "D:''Thyagu''AutoCAD14''4 sheet2.dwg", LayoutName = "layoutFour", LayoutTitle = "sheet2" }
[3] = { LayoutLocation = "D:''Thyagu''AutoCAD14''5 sheet3.dwg", LayoutName = "layoutFive", LayoutTitle = "sheet3" }
[4] = { LayoutLocation = "D:''Thyagu''AutoCAD14''6 t1.dwg", LayoutName = "layoutSix", LayoutTitle = "t1" }
如果您只是考虑将 XML 转换为分隔文本文档,而不执行任何广泛的添加逻辑,我实际上建议您使用 XSLT 来解析 XML 文件。
使用此方法而不是在代码中解析 XML(使用 XMLDocument、XPath、Linq 或任何其他解决方案(,只需更改所使用的 XSLT 映射文件,即可重新配置解析而无需重新编译代码。
如果您不熟悉 XSLT,这里有几篇文章可以让你入门:
在 C# 中使用 XSLT 和编写 XSLT
另请注意,您提供的 XML 内容已损坏,有一个多余的">AcSmSubset"结束标记