ソフトウェア開発者の日常

こだわりなく書きたいことを書いていきます。

Visual Basic 2013でXMLを操作

データがXML形式で書かれているファイルを変更しなくてはならなくなったので調べました。

変更前のXML形式のデータは以下のとおりです。

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<p:sld xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main">
  <p:cSld>
    <p:spTree>
      <p:pic>
        <p:nvPicPr>
          <p:nvPr>
            <p:extLst>
              <p:ext uri="{DAA4B4D4-6D71-4841-9C94-3DE7FCFB9230}">
                <p14:media xmlns:p14="http://schemas.microsoft.com/office/powerpoint/2010/main" r:embed="rId1" />
              </p:ext>
            </p:extLst>
          </p:nvPr>
        </p:nvPicPr>
      </p:pic>
    </p:spTree>
  </p:cSld>
</p:sld>

変更後のXML形式のデータは以下のとおりです。

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<p:sld xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main">
  <p:cSld>
    <p:spTree>
      <p:pic>
        <p:nvPicPr>
          <p:nvPr>
            <p:extLst>
              <p:ext uri="{DAA4B4D4-6D71-4841-9C94-3DE7FCFB9230}">
                <p14:media xmlns:p14="http://schemas.microsoft.com/office/powerpoint/2010/main" r:link="rId1" />
              </p:ext>
            </p:extLst>
          </p:nvPr>
        </p:nvPicPr>
      </p:pic>
    </p:spTree>
  </p:cSld>
</p:sld>

変更しているのは

<p14:media xmlns:p14="http://schemas.microsoft.com/office/powerpoint/2010/main" r:embed="rId1" /><p14:media xmlns:p14="http://schemas.microsoft.com/office/powerpoint/2010/main" r:link="rId1" />

の部分だけです。

以下のソースコードで、変更することができました。

Dim xml As XDocument
xml = XDocument.Load("C:\Users\test\Desktop\now.xml")

'名前空間を定義
Dim nsp As XNamespace = "http://schemas.openxmlformats.org/officeDocument/2006/relationships"
Dim nsp14 As XNamespace = "http://schemas.microsoft.com/office/powerpoint/2010/main"

'処理したいツリーを選択
Dim resp14 = From num In xml.Root.Descendants(nsp14 + "media")

'変更処理
Dim embedValue As String
For Each res In resp14

    embedValue$ = res.Attribute(nsp + "embed").Value.ToString

    res.SetAttributeValue(nsp + "link", embedValue$)

    res.SetAttributeValue(nsp + "embed", Nothing)

Next

'BOM付になるので利用しない
'xml.Save("C:\Users\test\Desktop\new.xml")

Dim xws As XmlWriterSettings = New XmlWriterSettings()
xws.Encoding = New UTF8Encoding(False)

Using xw = XmlWriter.Create("C:\Users\test\Desktop\new.xml", xws)
    xml.WriteTo(xw)
End Using
  • 名前空間の扱いがわからなくて、検索とテストを繰り返しました。
  • r:embedをr:linkに直接書き換えられないので、r:embedの値を取得して、r:linkを追加後、r:embedを削除しています。
  • XDocument.Save()メソッドで保存すると、BOMが付いてしまします。
    BOMなしにするために、XDocument.WriteTo()メソッドで保存しています。