65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 LINQ to XML 进行 MP3 标签 XML 写入器和 XSD 验证

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.38/5 (5投票s)

2008年11月20日

CPOL

5分钟阅读

viewsIcon

30865

downloadIcon

328

创建 MP3 标签 XML 文件并对其进行验证。

引言

我使用记事本已经有一段时间了,并用它来创建各种类型的文件。我最近想为我的 MP3 收藏创建一个 XML 文件,发现为 350 多个 MP3 文件编写 5 到 8 个标签将是一项艰巨的任务(对我来说,打字就是一项任务)。所以,我决定创建一个程序来完成这项工作,并将验证作为额外的功能。

在我上大学的时候(大约 20 年前),我们的教授总是让我们在创建程序时使用某种伪代码来遵循,我完全忘记了它,直到我决定制作这个程序。

这是伪代码……短版本

  • 设计用户界面(使用下面的伪代码)
  • 创建一个带有XML扩展名的文件名
  • 验证,然后如果文件名有效则接受
  • 选择 MP3 并将它们添加到列表框
  • 创建标签并将其写入文件
  • 在列表框中向用户显示我们迄今为止所做的工作
  • 使用 XSD(LINQ to XML)验证文件
  • 验证后,打开文件查看我们的成果
  • 最后……重置,如果需要,重复

起点

XMLWriter/xml2.jpg

XML 写入器开始时,所有按钮都处于禁用状态。您必须完成第一个任务才能继续下一个任务。在创建文件名、验证文件名、选择 MP3 并写入标签后,我们现在进入验证部分。我们现在可以验证我们刚刚创建的文件。

Private Sub buttonValidate_Click(ByVal sender As System.Object, _
                                 ByVal e As System.EventArgs) _
                                 Handles buttonValidate.Click
    lstActions.Items.Add("Linking (LINQ to XML using XSD)")
    'XSD code was in ms-help
    'I re-edited it to fit the output in the xml file
    Dim xsdMarkup As XElement = _
    <schema xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" />
        <element name=""MP3Info"" />
            <complextype />
                <sequence maxoccurs=""unbounded"" />
                    <element name=""TrackTitle"" type=""xsd:string"" />
                    <element name=""Artist"" type=""xsd:string"" />
                    <element name=""Length"" type=""xsd:string"" />
                    <element name=""Title"" type=""xsd:string"" />
                    <element name=""Genre"" type=""xsd:string"" />
                </sequence />
            </complextype />
        </element />
    </schema />

    Dim schemas As XmlSchemaSet = New XmlSchemaSet()
    schemas.Add("", xsdMarkup.CreateReader)

    lstActions.Items.Add("Attempting to Validate")

    Dim myDoc As XDocument = XDocument.Load(path & Trim(txtFileXML.Text))

    errors = False
    myDoc.Validate(schemas, AddressOf XSDErrors)

    If errors = True Then
        isValid = False
        lstActions.Items.Add("File is InValid")
        lblStatus.Text = "Invalid..."
        buttonOpen.Enabled = True
        Exit Sub
    Else
        isValid = True
        lstActions.Items.Add("File is Valid")
        lblStatus.Text = "Valid..."
    End If
    buttonOpen.Enabled = True
End Sub

XMLWriter/xml3.jpg

我在 MS-Help 中搜索了代码,但只找到了旧代码,这些代码与 .NET 3.5 版本不太兼容。大多数代码都是为 .NET 1.1 版本编写的,后来我因为代码错误才发现这一点。我还发现使用 XML 时不允许出现错误。如果出现错误,您的程序就会崩溃。因此,您必须编写无错误的代码,我通过反复试验,使用我在 MS-Help 中找到的各种小技巧,最终完成了这项工作。

Private Sub loadFiles(ByVal mediaType As String)
    Dim supportedFiles As String

    Select Case mediaType
        Case "Audio"
            supportedFiles = audioFiles
        Case Else
            supportedFiles = audioFiles
    End Select

    lstActions.Items.Add("Please wait...Creating File")

    With ofd 'OpenFileDialog Control
        .InitialDirectory = strPath
        .Filter = supportedFiles
        .CheckFileExists = True
        .Multiselect = True
        .RestoreDirectory = True
    End With

    If ofd.ShowDialog = Windows.Forms.DialogResult.OK Then

        Using sw As StreamWriter = File.CreateText(path & Trim(txtFileXML.Text))
            sw.WriteLine("")
            sw.WriteLine("<mp3info />") 'Opening Tag for MP3Info

            For Each Me.strFilePath In ofd.FileNames
                strFileShow = GetFileName(strFilePath)
                lstMP3.Items.Add(strFilePath)
                MMedia.LoadMedia(strFilePath)
                Dim fileInfo As New clsID3v1Reader(strFilePath)
                'sw.WriteLine("<mp3info />") 'Opening Tag for MP3Info
                sw.WriteLine("    <tracktitle />" & fileInfo.TrackTitle & _
                             "</tracktitle />")
                sw.WriteLine("    <artist />" & fileInfo.Artist & "</artist />")

                'Lets get the time length of the mp3 file.
                Dim secx, minx, mediaTotal As String
                Dim mediaTimes As String
                mediaTotal = CStr(Int(MMedia.MediaDuration))
                'If mediaTotal < 1 Then mediaTotal = 1
                secx = CStr(CDbl(mediaTotal) - (Int(CDbl(mediaTotal) / 60) * 60))
                minx = CStr(Int((CDbl(mediaTotal) - 
                            Int(CDbl(mediaTotal) / 3600) * 3600) / 60))
                mediaTimes = minx.ToString() & ":" & secx.ToString

                sw.WriteLine("    <length />" & mediaTimes & "</length />")
                MMedia.UnLoadMedia(strFilePath)
                sw.WriteLine("    ")
                sw.WriteLine("    <genre />" & GetGenre(currentMP3) & "</genre />")
                'sw.WriteLine("</mp3info />") 'Closing Tag for MP3Info
                sw.WriteLine()
            Next

            sw.WriteLine("</mp3info />") 'Closing Tag for MP3Info

            'Lets close the writer.
            sw.Close()

        End Using
    End If

    'Display again what we are doing for the user...
    lstActions.Items.Add("File created - " & Trim(txtFileXML.Text))
    lstActions.Items.Add("# of files selected..." & (lstMP3.Items.Count).ToString)
    lblStatus.Text = (lstMP3.Items.Count).ToString & " files selected"

    'Make unenabled, Enabled.
    buttonValidate.Enabled = True
End Sub

接下来……我们可以打开我们刚刚创建的新文件来查看我们辛勤工作的成果。我使用了Process类来打开记事本并显示我们的文件。

XMLWriter/xml4.jpg

XMLWriter/xml5.jpg

Private Sub buttonOpen_Click(ByVal sender As System.Object, _
                             ByVal e As System.EventArgs) Handles buttonOpen.Click
    ProcessNotepad.StartInfo.FileName = path & Trim(txtFileXML.Text)
    ProcessNotepad.Start()
    ProcessNotepad.WaitForExit()
    buttonReset.Enabled = True
End Sub

Using the Code

XML 写入器创建的mp3tag.xml文件可以用作 WPF 或 Blend 的数据源、播放列表,或 XML 文件可以用于的其他任何用途。我认为它是一个很好的实用工具,但那只是我的一厢情愿。

我在这个程序中使用的类是在此网站和 MS-Help 上找到的已重新编辑的类。clsDirectXAudio.vb来自 MMPlayer,可以在此网站上找到;clsID3TagReader.vb我认为在“Managing a MP3 Collection”中,该文件在 MS-Help 上是 MS-Word 文档格式。最后一点,程序不能在 IDE 中运行,它会抛出托管代码异常。制作一个.exe文件并在 IDE 外运行,它就可以正常工作。

关注点

当我刚开始这个项目时,我对 LINQ、XSD 或 XML 一无所知,现在我比开始时知道得更多了(开始时我脑袋里空空如也)。

在我修复一些错误之前,请不要下载。我完全忘记了撇号、和号以及小于号和大于号。我不知道如何在string中读取字符,即使我找到了方法,也不知道如何使用代码(最好是 VB.NET)替换它们。感谢您的耐心等待。如果有人能指出我正确的方向,我将不胜感激!

XMLWriter/xml-start.jpg

更新

在原始的XMLWriter中,存在设计缺陷,导致了一些棘手的异常。当遇到和号或撇号时,它会抛出异常。我通过在正确的位置进行几次替换操作来修复它。我还重新编写了隐藏在程序中作为标签的伪代码。请看下面的图片。

XMLWriter/xml-accept.jpg

Using the Code

程序启动后(介绍图片),您将输入一个带有 XML 扩展名的文件名,然后按接受按钮(上图)。接下来...

XMLWriter/xml-Created.jpg

输入任意数量的 MP3 文件,程序将创建您的 XML 文件并将其显示在listbox中。上图。接下来...

XMLWriter/xml-validate.jpg

我们验证新创建的 XML 文件。通过在正确的位置使用几次替换操作,这解决了在选择带有 ampersands 或 apostrophies 的 MP3 文件(例如:Brooks & Dunn - She's not the cheatin' Kind)的 tracktitle、title 或 artist 时发生的异常。这会导致程序崩溃。现在已经修复。上图。接下来……只需按下重置按钮,您就可以重新开始所有操作。多次执行此操作作为 WPF® 或 Blend® 的播放列表很有用。下图。

XMLWriter/xml-reset.jpg

全体致歉

如果您下载了原始的XMLWriter,请将其删除并使用此更新版本。它的工作效果更好,结果也更好。对于我这个小小的思维失误可能给您带来的任何不便,我深表歉意。再次……全体致歉。

致作者…

对于我使用的代码的所有作者(所有姓名都在程序注释中),我非常感谢大家。特别感谢 MS-Help 拥有如此庞大的知识库。

© . All rights reserved.