我有代码循环遍历多个文档中的XML元素,并检查数组中的匹配值(cpltfids)。如果它找到任何XML元素中某个数组值的匹配项,则会为XML中找到的文件创建硬链接。
循环适用于创建所有硬链接,但我很难添加代码来做更多的事情:
如果在任何XML中都找不到任何数组值,请停止并不执行任何操作。
返回循环结束时从未找到的所有数组值的值,因此我可以将它们写入最后的消息框/写入行。
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);
}
更新
感谢您的评论。我是新手。
我正在尝试做的总结:
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>
`
答案 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);
}
}
}