【问题标题】:Dynamically creating XElements inside XDocument using a loop使用循环在 XDocument 中动态创建 XElement
【发布时间】:2015-08-21 09:39:11
【问题描述】:

我需要能够使用循环在 XDocument 中动态创建“n”个 XElement,具体取决于在目录中找到的文件数。

我的 WIP 基本项目代码可能有点长,无法粘贴到此处,因此我已将其添加到 paste.org - here

您将在第 73-91 行之间看到我有一个 foreach 循环,它搜索目录及其子目录并定位其中包含的所有文件的路径。 我知道这是我用过的自己的作品:

int x = filePaths.Length;

x 的输出与给定目录中的文件数匹配。

代码的主要部分也可以工作,并根据我的需要创建一个 HTML 文件,但我还需要它在我放置的第 215 行之间动态创建“n”个 XElement:

/// **** NEED TO INSERT LOOP HERE TO DYNAMICALLY CREATE NUMBER OF ELEMENTS DEPENDING ON NUMBER OF FILES IN DIRECTORY ****

就在 <TR> 标记和第 280 行打开之前,就在 <TR> 标记关闭之后,因此在指定目录中找到的每个文件都有自己的 <TABLE> 行。

我已经记不清有多少种方法尝试通过在整个代码中移动循环来实现这一点,但总是遇到大量错误。

最初我认为只需将循环放在第 215 行的代码中就可以了,但这样做会导致许多错误,例如丢失:

  • ;
  • }

等等……

现在我完全被卡住了。

我正在尝试在 C# 中模拟我前段时间使用 WMIC 制作的批处理文件,该文件运行良好但功能有限,我希望添加更多功能,这就是 C# 的用武之地。

批处理文件使用循环,就像我在这里尝试的那样,完全没有任何问题。

这是来自 WMIC 批处理文件的循环:

(FOR /f "delims=" %%a IN ('dir /b /a-d /s /n "C:\Users\1CM69\Pics & Vids\Archives\Family\2002"') DO (
FOR /f "tokens=1-3*" %%x IN ('dir /a-d /tc "%%~a"^|findstr "^[0-9]"') DO (
  for /f %%c in ("%%~ta") do (
ECHO ^<TR^>^<td style="border-width: 1px;padding: 10px;border-style: inset;border-color: gray;background-color: white;" align="center" valign="middle"^>^<a href="%%a" target="_new"^>^<img src="%%a" width="100px" border="0"^>^</a^>^</TD^>^<td style="border-width: 1px;padding: 10px;border-style: inset;border-color: gray;background-color: white;" align="left" valign="middle"^>^<B^>%%~nxa^</B^>^</TD^>^<td style="border-width: 1px;padding: 10px;border-style: inset;border-color: gray;background-color: white;" align="center" valign="middle"^>^<B^>%%~c^</B^>^</TD^>^<td style="border-width: 1px;padding: 10px;border-style: inset;border-color: gray;background-color: white;" align="center" valign="middle"^>^<B^>%%x^</B^>^</TD^>^</TR^> >> 2002.html))))

我发现 Create XML with XDocument with a variable number of XElements using for loop 会四处搜索 & 最初是有希望的,虽然我确实让它根据文件数动态创建“n”个 XElement,但变量 DateTaken 只显示了最后一个文件的值在目录中,所以我有一个 &lt;TABLE&gt; 和 68 行 &lt;TR&gt;,在我使用的测试目录的情况下,它们都包含从循环找到的最终文件中检索到的值。

任何帮助将不胜感激。

问候..,

【问题讨论】:

    标签: c# html foreach linq-to-xml xelement


    【解决方案1】:

    不要使用循环,使用 LINQ from .. select .. 表达式,例如

    from file in filePaths
    select new XElement("tr", 
      new XElement("td",
        new XElement("a", new XAttribute("href", file), new XAttribute("target", "_new"), new XElement("img", new XAttribute("src", file), new XAttribute("width", "100"))),
        new XElement("td", file),
        new XElement("td", GetDate(file))
      ))
    

    要提取日期,请编写一个封装代码的方法,例如

    string GetDate(string path) {
    
    try
                                            {
    
                                            Bitmap MyPhoto = new Bitmap(file);
                                            const int IDDateTimeOriginal = 36867;
                                            PropertyItem TakenDate = MyPhoto.GetPropertyItem(IDDateTimeOriginal);
                                            Encoding ascii = Encoding.ASCII;
                                            return ascii.GetString(TakenDate.Value, 0, TakenDate.Len - 1);
                                            }
    
    
                                            catch //(ArgumentException) if the property doesn't exists
                                            {
                                              return "MISSING ENTRY";
                                            }
    }
    

    【讨论】:

    • 嗨,最初这似乎是一个简单的合乎逻辑的答案,并且做了一些工作。它根据文件数创建了正确的行数,但同样,只有目录中最后一个文件的值填充了表中的每一行。我有点迷路了……
    • 您能否向我们展示您要为filePaths 变量中的示例文件路径创建的示例表格行的HTML?恐怕WMIC示例不是我理解的。
    • 链接到输出的&lt;TABLE&gt; 的缩短版本。我有 &lt;TABLE&gt; 标题部分以增加清晰度。我知道我的代码尚未处理 &lt;TABLE&gt; 的 THUMBNAIL 列或 FILENAME 列的填充,但在第一次解决此问题后,从 filePaths 变量中检索数据应该是轻而易举的事。您可以看到 DATE TAKEN 列填充了来自特定图像 EXIF 数据的 DateTimeOriginal 字段,这应该通过迭代对目录内的所有图像完成。 link
    • 这里的批处理文件正是我想要在 C# 中实现的。 LINK 这可能会有所帮助。
    • 抱歉,Stack Overflow 新手,回复时忘记添加评论者姓名,所以:@martin
    【解决方案2】:

    如果您使用的是 XElements,它们旨在与 Linq 一起使用,因此请尝试以下操作:

    var filePaths = GetFiles(@"C:\SomeDir");
    var xml = new XElement("tr", 
        filePaths.Select(fp => new XElement("td", fp.FullName)));
    

    【讨论】:

    • 您好,感谢您的回复,但我不知道我需要在代码中的哪个位置插入此内容。
    • 当把它放在我想要新的&lt;TR&gt; 的位置附近时,我得到很多很多以var 开头的错误,在这种情况下不可用,它要求) 之后) & ; 到处都是,但似乎从不快乐。
    • 抱歉,Stack Overflow 新手,回复时忘记添加评论者姓名,所以:@mant101
    • 我查看了您的代码,但您确实需要将所有 XML 创建分解为子函数以使其可读。我猜想把new XElement("tr", filePaths.Select(fp =&gt; new XElement("td", fp)));放在你有/// **** NEED TO INSERT LOOP HERE TO DYNAMICALLY CREATE NUMBER OF ELEMENTS DEPENDING ON NUMBER OF FILES IN DIRECTORY ****的地方。如果 td 需要属性或其他什么,您可能需要更改 Select 的主体以执行您需要的任何操作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-24
    • 2016-03-09
    • 2012-11-07
    相关资源
    最近更新 更多