2014-12-17 2 views
0


Я начинаю с разбора XML. И я попробовал много примеров, чтобы прочитать этот XML и проанализировать только нужные вещи. Я хочу знать, какой из них будет лучшим вариантом - XML ​​или Linq.
Это мой XML:
Как разобрать сложный XML с атрибутом как условие в C#

<?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 является проект, он может содержать не папки (подмножества) и листы.
Папка (подмножество) может содержать любое количество папок (подмножеств) и листов.
И каждый лист должен иметь свойство с именем layout.
Я хочу получить свойства макета в одиночку.

Выход мне нужно:
LayoutLocation, LayoutName, LayoutTitle,
, который был бы в любом заданном формате (List, DataTable, независимо,.)
«D:... \ Тиагу \ AutoCAD14 \ 1 layoutrenamesheet .dwg», layoutOne, layoutrenamesheet,
... "D:... \ Тиагу \ AutoCAD14 \ 6 t1.dwg", layoutSix, t1,

Я сделал R & D на это так много времени, но все же я не получил решения для этого.

C# код I Used:

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». Так что я не могу получить доступ к листам, находящимся под подпапкой любой подпапки.

Спасибо,

+1

Вы добавили только XML. Добавьте код C#. В противном случае его неясно, в чем ваша проблема с разбором –

+0

Неясно, насколько ваше исследование заняло вас. Я бы * определенно * предложил использовать LINQ to XML ... но нелегко понять, как ваш образец XML (который, вероятно, дольше, чем нам действительно нужен в качестве примера), сопоставляется с ожидаемым результатом. Если вы всегда знаете имена элементов и значения 'propname', которые вы пытаетесь извлечь, остальное довольно просто. –

+0

LayoutTitle происходит от элемента AcSmProp? –

ответ

0

Самый простой способ обхода XML-документы и выполнять сложные запросы на них Linq-to-XML.

Используя это утверждение:

XDocument doc = XDocument.Load(@"somePath\myXMLFile.xml"); 

вы можете загрузить в XDocument вся структура XML дерево.

Вы можете использовать Descendants метод для того, чтобы получить всехAcSmSheet элементов, содержащихся в документе XML, независимо от их расположений. Имея это можно выполнить следующий запрос, чтобы вернуть необходимый набор результатов:

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         
       }; 

Использование XML-фрагмент, представленную в OP выше запрос дает следующие результаты:

[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" } 
0

Если вы только глядя на преобразование XML в разделителях текстового документа, без выполнения каких-либо обширных добавляемых логик, я бы на самом деле рекомендую вам об использовании XSLT для синтаксического анализа файла XML.

Использование этого вместо разбора XML-кода (с использованием XMLDocument, XPath, Linq или любого другого решения) дает вам дополнительное преимущество переконфигурировать ваш синтаксический анализ без перекомпиляции кода, просто изменив используемый файл сопоставления XSLT ,

В случае, если вы новичок в XSLT, вот несколько статей, чтобы начать Вас:

Using XSLT in C# & Writing XSLT

Также обратите внимание, что содержание XML Предоставленный сломана, есть один избыток " AcSmSubset "закрывающий тег

+0

Нет, я просто хочу прочитать данные XML. это оно. Благодарю. – Thiyagarajan

Смежные вопросы