XMLファイルには、さまざまな要素のある&属性があります。いくつかはすべてに共通していますが、すべてのノードにすべての(または同じ)ノードがあるわけではありません。次のようにサンプルXMLは次のとおりです。ダイナミックXMLをCSV /テキストに変換する
<?xml version='1.0' encoding='UTF-8'?>
<index>
<doc id='0'>
<field name='IDTREE' norm='124' flags='Idfp--S--Ni08--------'>
<val>-</val>
</field>
<field name='role' norm='114' flags='Idfp--S--Ni08--------'>
<val>administrators</val>
</field>
<field name='internalid' norm='117' flags='Idfp--S--Ni08--------'>
<val>123456</val>
</field>
<field name='version' norm='124' flags='Idfp--S--Ni08--------'>
<val>test</val>
</field>
<field name='id' norm='124' flags='Idfp--S--Ni08--------'>
<val>myname-123456-test</val>
</field>
<field name='siteId' norm='124' flags='Idfp--S--Ni08--------'>
<val>myname</val>
</field>
</doc>
<doc id='1'>
<field name='internalid' norm='117' flags='Idfp--S--Ni08--------'>
<val>98765</val>
</field>
<field name='version' norm='124' flags='Idfp--S--Ni08--------'>
<val>dev</val>
</field>
<field name='category' norm='113' flags='Idfp--S--Ni08--------'>
<val>biography</val>
</field>
<field name='display' norm='120' flags='Idfp--S--Ni08--------'>
<val>false</val>
</field>
<field name='publisher' norm='124' flags='Idfp--S--Ni08--------'>
<val>-</val>
</field>
<field name='id' norm='124' flags='Idfp--S--Ni08--------'>
<val>myname-98765-dev</val>
</field>
<field name='siteId' norm='124' flags='Idfp--S--Ni08--------'>
<val>myname</val>
</field>
</doc>
</index>
私が何をしたいのか、私はエクセル(またはSQL)にインポートできるテキストファイル(パイプ区切り)にこの(非常に大きい)XMLファイルを変換することです。私は、列名を取得するための最初の1、および第2の適切なフィールドにデータを追加するために、XMLデータに2回のパスを作成する必要があると思い
id|siteId|version|internalid|role|IDTREE|category|display|publisher myname-123456-test|myname|test|123456|administrators|-||| myname-98765-dev|myname|dev|98765|||biography|false|-
:ように私は出力になりたいですテキストファイルに出力する。
私は、各ドキュメントに同じフィールドノードが少なくとも4つあることを知っています:id、siteId、versionおよびinternalid。他のすべてはさまざまです。
私の最初の考えは、XMLの1パスを行い、フィールドの名前属性をハッシュテーブルに追加することでした。 2番目のパスでは、ハッシュテーブルを使用して、&をループして、出力上の適切な場所に各フィールドを割り当てます。
私は今XMLファイルを読むためにこれを使用しています。
$f = [System.Xml.XmlReader]::Create("C:\Test\MyXMLFile.xml")
while ($f.read()) {
switch ($f.NodeType) {
([System.Xml.XmlNodeType]::Element) {
if ($f.Name -eq "doc") {
$e = [System.Xml.Linq.XElement]::ReadFrom($f)
$nbr = [String] $e.Attribute("id").Value
$fields = $e.Descendants("field")
foreach ($fld in $fields) {
$z = $fld.FirstAttribute.Value
$z1 = $fld.Element("val").Value
}
# write output
}
}
}
}
私が検討している方法よりも良い方法がありますか?
それはあなたに良い意味であるかどうかによって異なります –
@ MathiasR.Jessen - 残念なことに、「より良い」は必ずしもw帽子それは言う。この場合、「より良い」というのは簡単だと思います。しかし現実の世界では、「より良い」とはしばしば悪臭を放つオプションを意味します。 ;) –