c#返回未找到的所有数组值

时间:2018-03-17 22:36:04

标签: c# arrays

我有代码循环遍历多个文档中的XML元素,并检查数组中的匹配值(cpltfids)。如果它找到任何XML元素中某个数组值的匹配项,则会为XML中找到的文件创建硬链接。

循环适用于创建所有硬链接,但我很难添加代码来做更多的事情:

  1. 如果在任何XML中都找不到任何数组值,请停止并不执行任何操作。

  2. 返回循环结束时从未找到的所有数组值的值,因此我可以将它们写入最后的消息框/写入行。

    foreach (var assetC in assetElements)
    {
        var innerElementsC = assetC.Descendants(assetns + "Id").FirstOrDefault().Value;
    
        if (!Array.Exists(cpltfids, element => element.Value == (innerElementsC)))
            continue;
    
        var assetname = assetC.Descendants(assetns + "Path").FirstOrDefault().Value;
        var assetpath = Directory.GetFiles(assetmapdir, (assetname))[0].ToString();
    
        CreateHardLink(Path.Combine(textBox3.Text, (assetname)), (assetpath), IntPtr.Zero);
    
    }
    
  3. 更新

    感谢您的评论。我是新手。

    我正在尝试做的总结:

    1. 用户将x个“CPL xml文档加载到列表框中。
    2. 从加载的xml中搜索x个目录(我将稍后添加更多迭代)并查找名为ASSETMAP.xml的x个文件
    3. 解析所有ASSETMAP.xml文件,看看在用户加载的xml中是否存在与uuid的uuid匹配。
    4. 对于找到的所有匹配项,构建这些uuids所属文件的路径,并为用户指定的目录中的每个文件创建一个硬链接。
    5. foreach循环位于我在程序中其他地方调用的方法中。以下是更多背景信息:

      方式:

      public bool UpdateNameInAssetmap(XDocument doc, string uuid, string newName)
          {
              var ns = doc.Root.GetDefaultNamespace();
              var assetElements = doc.Descendants(ns + "Asset");
              var result = false;
      
              foreach (var assetC in assetElements)
              {
                  var innerElementsC = assetC.Descendants(ns + "Id").First(); //nav to uuid id element in assetmap 
                  if (!innerElementsC.Value.Equals(uuid))
                      continue;
      
                  var chunks = assetC.Elements(ns + "ChunkList").First().Elements(); //nav to chunk list element
      
                  foreach (var chunk in chunks)
                  {
                      chunk.Elements(ns + "Path").First().SetValue(newName); //update path element to new filename in assetmap
                  }
      
                  result = true;
              }
      
              return result;
          }
      

      我在调用方法的地方:

      在这个例子中,我要说的是从用户选择的ASSETMAP.xml的XML中查找3个目录:

      private void button5_Click(object sender, EventArgs e)
          {
              try
              {
                  if (checkBox4.Checked)
                  {     
                      var myList = listBox1.Items.Cast<String>().ToList();
      
                      foreach (var listitem in myList)
                      {
                          string folder = Path.GetFullPath(Path.Combine(listitem, "..\\..\\..\\"));
                          FindChildren(listitem, folder);
                      }
                  }
              }
              catch (Exception)
              {
                  throw;
              }                      
          }
      

      我正在解析的简化XML,用于创建要查找的uuid数组:

      <?xml version="1.0" encoding="UTF-8"?>
      <CompositionPlaylist xmlns="http://www.smpte-ra.org/schemas/2067-3/2016" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <Id>urn:uuid:f3412d2a-b7c6-4b88-8298-4b1287eb6b7f</Id>
        <Annotation>test</Annotation>
        <IssueDate>2018-03-14T18:04:50-00:00</IssueDate>
        <SegmentList>
      <Segment>
        <Id>urn:uuid:2213e126-8943-44f2-b648-2ee1966bcae6</Id>
        <SequenceList>
          <cc:MainImageSequence xmlns:cc="http://www.smpte-ra.org/schemas/2067-2/2016">
            <Id>urn:uuid:f24457fa-f9f0-4f98-823d-37b315076846</Id>
            <TrackId>urn:uuid:4fe07410-9a36-41e8-90dc-6d948b6c9965</TrackId>
            <ResourceList>
              <Resource xsi:type="TrackFileResourceType">
                <Id>urn:uuid:e6dda0de-d3b3-4132-b243-c5a32f906071</Id>
                <Annotation>VIDEO_e6dda0de-d3b3-4132-b243-c5a32f906071.mxf</Annotation>
                <EditRate>24000 1001</EditRate>
                <IntrinsicDuration>120</IntrinsicDuration>
                <EntryPoint>0</EntryPoint>
                <SourceDuration>120</SourceDuration>
                <SourceEncoding>urn:uuid:b54c9259-db31-4c26-a2f1-1fb2d9289a91</SourceEncoding>
                <TrackFileId>urn:uuid:e6dda0de-d3b3-4132-b243-c5a32f906071</TrackFileId>
                <Hash>6dj4cRq4fjj0hFHiCkzelQaBsmI=</Hash>
              </Resource>
            </ResourceList>
          </cc:MainImageSequence>
          <cc:MainAudioSequence xmlns:cc="http://www.smpte-ra.org/schemas/2067-2/2016">
            <Id>urn:uuid:0482c0a9-a9bf-4eef-8242-827f5fc0ed04</Id>
            <TrackId>urn:uuid:8ee689f1-d8d2-47d0-9aab-0649bc8dd107</TrackId>
            <ResourceList>
              <Resource xsi:type="TrackFileResourceType">
                <Id>urn:uuid:d669a9dc-bb65-4e6c-8ca5-8c4c7db78366</Id>
                <Annotation>AUDIO_d669a9dc-bb65-4e6c-8ca5-8c4c7db78366.mxf</Annotation>
                <EditRate>48000 1</EditRate>
                <IntrinsicDuration>240240</IntrinsicDuration>
                <EntryPoint>0</EntryPoint>
                <SourceDuration>240240</SourceDuration>
                <SourceEncoding>urn:uuid:12c5eb01-05ec-4a52-a849-a93a75a81abe</SourceEncoding>
                <TrackFileId>urn:uuid:d669a9dc-bb65-4e6c-8ca5-8c4c7db78366</TrackFileId>
                <Hash>LqYEfjfJ4Ut868Ev7dEPAOZ2pQU=</Hash>
              </Resource>
            </ResourceList>
          </cc:MainAudioSequence>
          <cc:MainAudioSequence xmlns:cc="http://www.smpte-ra.org/schemas/2067-2/2016">
            <Id>urn:uuid:a982cff3-45b6-4c13-9983-10a1c4c7cba6</Id>
            <TrackId>urn:uuid:650715f4-fd76-49b8-af67-86064d68e883</TrackId>
            <ResourceList>
              <Resource xsi:type="TrackFileResourceType">
                <Id>urn:uuid:56b010e4-f3e1-46f6-87e9-80b6ea099651</Id>
                <Annotation>AUDIO_56b010e4-f3e1-46f6-87e9-80b6ea099651.mxf</Annotation>
                <EditRate>48000 1</EditRate>
                <IntrinsicDuration>240240</IntrinsicDuration>
                <EntryPoint>0</EntryPoint>
                <SourceDuration>240240</SourceDuration>
                <SourceEncoding>urn:uuid:2ddc6740-96ab-4a68-b9fb-57db49642089</SourceEncoding>
                <TrackFileId>urn:uuid:56b010e4-f3e1-46f6-87e9-80b6ea099651</TrackFileId>
                <Hash>4u6ErtEdI9pXNIMDrQ/EB/aKuw8=</Hash>
              </Resource>
            </ResourceList>
          </cc:MainAudioSequence>
          <cc:SubtitlesSequence xmlns:cc="http://www.smpte-ra.org/schemas/2067-2/2016">
            <Id>urn:uuid:d4825bd1-a294-41f7-820c-2b7658e06415</Id>
            <TrackId>urn:uuid:31535e83-89ee-4e29-a8f4-d9a36eaff215</TrackId>
            <ResourceList>
              <Resource xsi:type="TrackFileResourceType">
                <Id>urn:uuid:fbb9e1cc-6f2e-43b3-a01c-a3b34d04252a</Id>
                <Annotation>SUB_fbb9e1cc-6f2e-43b3-a01c-a3b34d04252a.mxf</Annotation>
                <EditRate>24000 1001</EditRate>
                <IntrinsicDuration>120</IntrinsicDuration>
                <EntryPoint>0</EntryPoint>
                <SourceDuration>120</SourceDuration>
                <SourceEncoding>urn:uuid:8562a7a6-43a4-4e30-bf6b-7b541ccfa900</SourceEncoding>
                <TrackFileId>urn:uuid:fbb9e1cc-6f2e-43b3-a01c-a3b34d04252a</TrackFileId>
                <Hash>eJVhYF6TuOo/vu7KE6qsmFqUnUk=</Hash>
              </Resource>
            </ResourceList>
          </cc:SubtitlesSequence>
        </SequenceList>
      </Segment>
      

      `

      我正在搜索的示例XML(ASSETMAP.xml)。可能有多个,因此是foreach循环。

      <?xml version="1.0" encoding="UTF-8"?>
      <AssetMap xmlns="http://www.smpte-ra.org/schemas/429-9/2007/AM">
        <Id>urn:uuid:94958496-dde9-49b0-ad50-1dda6d4bba67</Id>
        <Creator>test</Creator>
        <VolumeCount>1</VolumeCount>
        <IssueDate>2018-03-14T17:59:32-00:00</IssueDate>
        <AssetList>
          <Asset>
        <Id>urn:uuid:c1eab1db-5218-46c7-a05f-0e304083f604</Id>
        <PackingList>true</PackingList>
        <ChunkList>
          <Chunk>
            <Path>PKL_c1eab1db-5218-46c7-a05f-0e304083f604.xml</Path>
            <VolumeIndex>1</VolumeIndex>
            <Offset>0</Offset>
            <Length>3063</Length>
          </Chunk>
        </ChunkList>
      </Asset>
      <Asset>
        <Id>urn:uuid:393c1a9b-1907-4dd0-a3a9-5299b0dcdedf</Id>
        <ChunkList>
          <Chunk>
            <Path>CPL_IMF_JOT_Sample_ML5HDR10_OV.xml</Path>
            <VolumeIndex>1</VolumeIndex>
            <Offset>0</Offset>
            <Length>22807</Length>
          </Chunk>
        </ChunkList>
      </Asset>
      <Asset>
        <Id>urn:uuid:e6dda0de-d3b3-4132-b243-c5a32f906071</Id>
        <ChunkList>
          <Chunk>
            <Path>VIDEO_e6dda0de-d3b3-4132-b243-c5a32f906071.mxf</Path>
            <VolumeIndex>1</VolumeIndex>
            <Offset>0</Offset>
            <Length>14745242</Length>
          </Chunk>
        </ChunkList>
      </Asset>
      <Asset>
        <Id>urn:uuid:56b010e4-f3e1-46f6-87e9-80b6ea099651</Id>
        <ChunkList>
          <Chunk>
            <Path>AUDIO_56b010e4-f3e1-46f6-87e9-80b6ea099651.mxf</Path>
            <VolumeIndex>1</VolumeIndex>
            <Offset>0</Offset>
            <Length>4341294</Length>
          </Chunk>
        </ChunkList>
      </Asset>
      <Asset>
        <Id>urn:uuid:d669a9dc-bb65-4e6c-8ca5-8c4c7db78366</Id>
        <ChunkList>
          <Chunk>
            <Path>AUDIO_d669a9dc-bb65-4e6c-8ca5-8c4c7db78366.mxf</Path>
            <VolumeIndex>1</VolumeIndex>
            <Offset>0</Offset>
            <Length>1458414</Length>
          </Chunk>
        </ChunkList>
      </Asset>
      <Asset>
        <Id>urn:uuid:f17087ab-50ea-4537-8d1b-f53b54bd8ea8</Id>
        <ChunkList>
          <Chunk>
            <Path>SUB_f17087ab-50ea-4537-8d1b-f53b54bd8ea8.mxf</Path>
            <VolumeIndex>1</VolumeIndex>
            <Offset>0</Offset>
            <Length>34509</Length>
          </Chunk>
        </ChunkList>
      </Asset>
      <Asset>
        <Id>urn:uuid:809da04c-8daf-4835-9ae5-889e7f93d18e</Id>
        <ChunkList>
          <Chunk>
            <Path>OPL_809da04c-8daf-4835-9ae5-889e7f93d18e.xml</Path>
            <VolumeIndex>1</VolumeIndex>
            <Offset>0</Offset>
            <Length>725</Length>
          </Chunk>
        </ChunkList>
      </Asset>
      

      `

1 个答案:

答案 0 :(得分:1)

我喜欢使用词典来分组ID。下面我用xml linq来做所有的解析。以下只是一个开始,但如果您需要其他帮助,请告诉我。我不确定哪些ID需要匹配。以下代码未找到任何匹配项。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        static string[] cplFILENAMES = { @"c:\temp\test.xml" };
        static string[] assetFILENAMES = { @"c:\temp\test1.xml" };
        static void Main(string[] args)
        {
            foreach (string filename in cplFILENAMES)
            {
                new CompositionPlayList(filename);
            }
            foreach (string filename in assetFILENAMES)
            {
                new AssetMap(filename);
            }

            var groups = (from cpl in CompositionPlayList.dictSequences
                          join asset in AssetMap.dictAsset on cpl.Key equals asset.Key into a
                          from asset in a.DefaultIfEmpty()
                          select new { id = cpl.Key, cpl = cpl.Value, asset = asset.Value }).ToList();
        }
    }

    public class CompositionPlayList
    {

        public string filename { get; set; }
        public string id { get; set; }
        public DateTime issueDate { get; set; }
        public string segmentID { get; set; }

        public static Dictionary<string, Sequence> dictSequences = new Dictionary<string, Sequence>();

        public CompositionPlayList() { }
        public CompositionPlayList(string filename)
        {
            XDocument doc = XDocument.Load(filename);
            XElement cpl = doc.Root;
            XNamespace ns = cpl.GetDefaultNamespace();


            this.filename = filename;
            id = ((string)cpl.Element(ns + "Id")).Split(new char[] { ':' }).LastOrDefault();

            issueDate = (DateTime)cpl.Element(ns + "IssueDate");

            XElement segment = cpl.Descendants(ns + "Segment").FirstOrDefault();
            segmentID = ((string)segment.Element(ns + "Id")).Split(new char[] { ':' }).LastOrDefault();

            List<XElement> sequences = segment.Element(ns + "SequenceList").Elements().ToList();

            XNamespace ccNs = sequences.FirstOrDefault().GetNamespaceOfPrefix("cc");

            Dictionary<string, Sequence> newDictSequences = sequences.Select(x => new Sequence
            {
                sequenceType = x.Name.LocalName,
                id = ((string)x.Element(ns + "Id")).Split(new char[] { ':' }).LastOrDefault(),
                trackID = ((string)x.Element(ns + "TrackId")).Split(new char[] { ':' }).LastOrDefault()
                filename = filename;
            }).GroupBy(x => x.trackID, y => y)
            .ToDictionary(x => x.Key, y => y.FirstOrDefault());

            foreach (KeyValuePair<string, Sequence> sequence in newDictSequences)
            {
                dictSequences.Add(sequence.Key, sequence.Value);
            }
        }

    }
    public class Sequence
    {
        public string sequenceType { get; set; }
        public string id { get; set; }
        public string trackID { get; set; }
        public string filename { get; set; }
    }
    public class AssetMap
    {
        public string filename { get; set; }
        public string id { get; set; }
        public DateTime issueDate { get; set; }

        public static Dictionary<string, Asset> dictAsset = new Dictionary<string, Asset>();

        public AssetMap() { }
        public AssetMap(string filename)
        {
            XDocument doc = XDocument.Load(filename);
            XElement assetMap = doc.Root;
            XNamespace ns = assetMap.GetDefaultNamespace();

            this.filename = filename;
            id = ((string)assetMap.Element(ns + "Id")).Split(new char[] { ':' }).LastOrDefault();

            issueDate = (DateTime)assetMap.Element(ns + "IssueDate");

            List<XElement> assets = assetMap.Element(ns + "AssetList").Elements().ToList();

            Dictionary<string, Asset> newDictAsset = assets.Select(x => new Asset
            {
                id = ((string)x.Element(ns + "Id")).Split(new char[] { ':' }).LastOrDefault()
            }).GroupBy(x => x.id, y => y)
            .ToDictionary(x => x.Key, y => y.FirstOrDefault());

            foreach (KeyValuePair<string, Asset> sequence in newDictAsset)
            {
                dictAsset.Add(sequence.Key, sequence.Value);
            }
        }
    }
    public class Asset
    {
        public string id { get; set; }

    }

}

我最初使用字典来更快地查找。既然我使用了左外连接,那么字典是不需要的,所以下面是一个更有效的代码版本

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        static string[] cplFILENAMES = { @"c:\temp\test.xml" };
        static string[] assetFILENAMES = { @"c:\temp\test1.xml" };
        static void Main(string[] args)
        {
            foreach (string filename in cplFILENAMES)
            {
                new CompositionPlayList(filename);
            }
            foreach (string filename in assetFILENAMES)
            {
                new AssetMap(filename);
            }

            var groups = (from cpl in CompositionPlayList.sequences
                          join asset in AssetMap.assets on cpl.trackID equals asset.id into a
                          from asset in a.DefaultIfEmpty()
                          select new { id = cpl.id, cpl = cpl.trackID, asset = asset}).ToList();
        }
    }

    public class CompositionPlayList
    {

        public string filename { get; set; }
        public string id { get; set; }
        public DateTime issueDate { get; set; }
        public string segmentID { get; set; }

        public static List<Sequence> sequences = new List<Sequence>();

        public CompositionPlayList() { }
        public CompositionPlayList(string filename)
        {
            XDocument doc = XDocument.Load(filename);
            XElement cpl = doc.Root;
            XNamespace ns = cpl.GetDefaultNamespace();


            this.filename = filename;
            id = ((string)cpl.Element(ns + "Id")).Split(new char[] { ':' }).LastOrDefault();

            issueDate = (DateTime)cpl.Element(ns + "IssueDate");

            XElement segment = cpl.Descendants(ns + "Segment").FirstOrDefault();
            segmentID = ((string)segment.Element(ns + "Id")).Split(new char[] { ':' }).LastOrDefault();

            List<XElement> sequences = segment.Element(ns + "SequenceList").Elements().ToList();

            XNamespace ccNs = sequences.FirstOrDefault().GetNamespaceOfPrefix("cc");

            List<Sequence> newSequences = sequences.Select(x => new Sequence {
                sequenceType = x.Name.LocalName,
                id = ((string)x.Element(ns + "Id")).Split(new char[] { ':' }).LastOrDefault(),
                trackID = ((string)x.Element(ns + "TrackId")).Split(new char[] { ':' }).LastOrDefault(),
                filename = filename
            }).ToList();

            CompositionPlayList.sequences.AddRange(newSequences);
        }

    }
    public class Sequence
    {
        public string sequenceType { get; set; }
        public string id { get; set; }
        public string trackID { get; set; }
        public string filename { get; set; }
    }
    public class AssetMap
    {
        public string filename { get; set; }
        public string id { get; set; }
        public DateTime issueDate { get; set; }

        public static List<AssetMap> assets = new List<AssetMap>();

        public AssetMap() { }
        public AssetMap(string filename)
        {
            XDocument doc = XDocument.Load(filename);
            XElement assetMap = doc.Root;
            XNamespace ns = assetMap.GetDefaultNamespace();

            this.filename = filename;
            id = ((string)assetMap.Element(ns + "Id")).Split(new char[] { ':' }).LastOrDefault();

            issueDate = (DateTime)assetMap.Element(ns + "IssueDate");

            List<XElement> assets = assetMap.Element(ns + "AssetList").Elements().ToList();

            List<AssetMap> newAssets = assets.Select(x => new AssetMap() { id = ((string)x.Element(ns + "Id")).Split(new char[] { ':' }).LastOrDefault(), filename = filename, issueDate = issueDate }).ToList();

            AssetMap.assets.AddRange(newAssets);
        }
    }


}