Powershell Linq 查询,当存在多个相同名称的元素时

huangapple go评论62阅读模式
英文:

Powershell Linq query where multiple elements of same name exist

问题

I've translated the code portion for you:

我尝试将我的XML转换以将其导入到MS Access中一切都正常直到我需要迭代具有相同名称的元素

以下是我简化的XML示例

<?xml version="1.0" encoding="utf-8"?>
<data>
<orders>
<order>
<name>1</name>
<type>a</type>
<type>b</type>
</order>
</orders>
</data>
</xml>

以下是PowerShell脚本

using assembly System.Xml.Linq

$inputFilename = "1.xml"
$outputXmlFilename = "2.xml"

$doc = [System.Xml.Linq.XDocument]::Load($inputFilename)
$table = [System.Collections.ArrayList]::new()
$orders = $doc.Descendants("order")

foreach($order in $orders)
{

    $name = $order.Element("name").Value
    $newRow | Add-Member -NotePropertyName name -NotePropertyValue $name

    $table.Add($newRow) | Out-Null

}

$settings = New-Object System.Xml.XmlWriterSettings
$settings.Indent = $true
$settings.Encoding = [System.Text.Encoding]::UTF8

$writer = [System.Xml.XmlWriter]::Create($outputXmlFilename, $settings)
$writer.WriteStartElement("table")
$table | ForEach-Object {
   $writer.WriteStartElement("row")
   $props = $_.PSObject.Properties
   $props | ForEach-Object {
      $writer.WriteStartElement($_.Name)
      $writer.WriteString($_.Value)
      $writer.WriteEndElement()
   }
   $writer.WriteEndElement()
}
$writer.WriteEndElement()
$writer.Close()

Write-Output "Results saved to $outputXmlFilename"

I hope this helps. If you have any further questions or need additional assistance, please let me know.

英文:

I try to transform my XML to import it into MS Access and everything works fine until I need to iterate over elements with the same name.

Here is my simplified XML example:

<?xml version="1.0" encoding="utf-8"?>
<data>
<orders>
<order>
<name>1</name>
<type>a</type>
<type>b</type>
</order>
</orders>
</data>
</xml>

Here is the Powershell script:

using assembly System.Xml.Linq

$inputFilename = "1.xml"
$outputXmlFilename = "2.xml"

$doc = [System.Xml.Linq.XDocument]::Load($inputFilename)
$table = [System.Collections.ArrayList]::new()
$orders = $doc.Descendants("order")




foreach($order in $orders)
{

		 
		  $name = $order.Element("name").Value
		  $newRow | Add-Member -NotePropertyName name -NotePropertyValue $name		 

		  
		 
		  $table.Add($newRow) | Out-Null
 
}

$settings = New-Object System.Xml.XmlWriterSettings
$settings.Indent = $true
$settings.Encoding = [System.Text.Encoding]::UTF8

$writer = [System.Xml.XmlWriter]::Create($outputXmlFilename, $settings)
$writer.WriteStartElement("table")
$table | ForEach-Object {
   $writer.WriteStartElement("row")
   $props = $_.PSObject.Properties
   $props | ForEach-Object {
      $writer.WriteStartElement($_.Name)
      $writer.WriteString($_.Value)
      $writer.WriteEndElement()
   }
   $writer.WriteEndElement()
}
$writer.WriteEndElement()
$writer.Close()

Write-Output "Results saved to $outputXmlFilename"

What I want to get:

<?xml version="1.0" encoding="utf-8"?>
<table>
  <row>
    <name>1</name>
    <types>a,b</types>
  </row>
</table>
</xml>

I tried to modify it like this but with no luck. I am not really sure if it's possible to iterate here.

   $mytypes = ""
   

		 if ($order.Element("type").Name -eq "type") {
		 $mytypes = $mytypes + $order.Element("type").Value
	 	}  

答案1

得分: 1

I managed to do it via XSLT transform. Code here:

<types>
<xsl:for-each select="type">
  <xsl:value-of select="."/>
  <xsl:if test="position() != last()">
	<xsl:text>, </xsl:text>
  </xsl:if>
</xsl:for-each>
</types>
英文:

I managed to do it via XSLT transform. Code here:

<types>
<xsl:for-each select="type">
  <xsl:value-of select="."/>
  <xsl:if test="position() != last()">
	<xsl:text>, </xsl:text>
  </xsl:if>
</xsl:for-each>
</types>

huangapple
  • 本文由 发表于 2023年4月7日 01:16:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/75952134.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定