簡體   English   中英

如何在C#中使用屬性作為條件解析復雜的XML

[英]How to parse complex XML with attribute as a condition in c#


我是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的結構:
換句話說: SheetSet是一個Project,它可能不包含任何文件夾(子集)和Sheets。
文件夾(子集)可以不包含任何文件夾(子集)和圖紙。
並且每個工作表應具有一個名為layout的屬性。
我想單獨獲得布局屬性。

我需要的輸出:
LayoutLocation。,LayoutName。,LayoutTitle。,
可以是任何設置的格式(列表,數據表等)
“ 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”標簽的位置不是標准的。
它會根據他在創建時描述的最終用戶格式而動態變化。
唯一的事情是Sheets總是以“ AcSmSheet”標簽開頭。 因此,我無法訪問任何子文件夾的子文件夾下的工作表。

謝謝,

如果您只是想將XML轉換為帶分隔符的文本文檔,而不執行任何擴展的邏輯,那么我實際上建議您使用XSLT來解析XML文件。

使用此方法而不是解析代碼中的XML(使用XMLDocument,XPath,Linq或任何其他解決方案),只需更改所使用的XSLT映射文件,即可獲得重新配置解析而不重新編譯代碼的額外好處。

如果您是XSLT的新手,請閱讀以下幾篇入門文章:

在C#中使用XSLT編寫XSLT

還請注意,您提供的XML內容已損壞,有一個多余的“ AcSmSubset ”結束標記

遍歷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" }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM