在Powershell /.Net中将XML转换为变量(类型对象)而不是文件

时间:2023-01-30 00:38:31

Hi All I an trying to transform xml stored as an XmlDocument object type using System.Xml.Xsl.XslCompiledTransform

大家好我尝试使用System.Xml.Xsl.XslCompiledTransform转换存储为XmlDocument对象类型的xml

I am trying to do this in Powershell. The input xml is in the form of an xml object type

我试图在Powershell中这样做。输入xml采用xml对象类型的形式

I have the actual transform stored as an external file.

我将实际转换存储为外部文件。

I want the transformed xml to be held in another xmlDocument type object and not written out to a file.

我希望转换后的xml保存在另一个xmlDocument类型对象中,而不是写入文件。

When I look up the docs on the System.Xml.Xsl.XslCompiledTransform class, there are several overloads of the transform method

当我在System.Xml.Xsl.XslCompiledTransform类上查找文档时,转换方法有几个重载

Each method variation wants to write the resultant transform to either a stream OR XmlWriter OR other file writing device, however I don't want to write the result to a file, I want to an XmlDocument object type to insert into another xml file.

每个方法变体都希望将结果转换写入流或XmlWriter或其他文件写入设备,但是我不想将结果写入文件,我想将XmlDocument对象类型插入到另一个xml文件中。

Reference is here: Reference Docs MSDN XslCompiledTransform Class

参考文献在这里:参考文档MSDN XslCompiledTransform类

Here is my xml as a

这是我的xml

$mydoc = [xml] @"
<metadata>
    <LOGLINE>Teena's First Horrific Slumber Party</LOGLINE>
    <YearVideoMade>1987</YearVideoMade>
    <LevelOfStudy>Masters</LevelOfStudy>
    <SYNOPSIS>Teena will never forget her first slumber party,blah</SYNOPSIS>
    <Director>Shirley Barrett</Director>
    <Writer>Shirley Barrett</Writer>
    <Producer>Edmund Milts/Shirley Barrett</Producer>
    <Cinematographer>Joanne Parker</Cinematographer>
    <Editor>Kym Vaitiekus</Editor>
    <ProductionDesigner>Diana Reynolds</ProductionDesigner>
    <LocationSound>Kate Gunn</LocationSound>
    <PostSound>Kate Gunn</PostSound>
    <AreaOfSpecialisation>Scriptwriting</AreaOfSpecialisation>
    <AFTRSSTUDENTKEYCREATIVECREW>Shirley Barrett: director</AFTRSSTUDENTKEYCREATIVECREW>
    <AFTRSSTUDENTKEYCREATIVECREW>Shirley Barrett: writer</AFTRSSTUDENTKEYCREATIVECREW>
    <AFTRSSTUDENTKEYCREATIVECREW>Edmund Milts/Shirley Barrett: producer</AFTRSSTUDENTKEYCREATIVECREW>
    <AFTRSSTUDENTKEYCREATIVECREW>Joanne Parker: cinematographer</AFTRSSTUDENTKEYCREATIVECREW>
    <AFTRSSTUDENTKEYCREATIVECREW>Kym Vaitiekus: editor</AFTRSSTUDENTKEYCREATIVECREW>
    <AFTRSSTUDENTKEYCREATIVECREW>Diana Reynolds: production designer</AFTRSSTUDENTKEYCREATIVECREW>
    <AFTRSSTUDENTKEYCREATIVECREW>Kate Gunn: location sound</AFTRSSTUDENTKEYCREATIVECREW>
    <AFTRSSTUDENTKEYCREATIVECREW>Kate Gunn: post sound</AFTRSSTUDENTKEYCREATIVECREW>
    <DirectorID>000000</DirectorID>
    <WriterID>000000</WriterID>
    <ProducerID>000000</ProducerID>
    <ProducerID>000000</ProducerID>
    <CinematographerID>000000000000</CinematographerID>
    <EditorID>000000</EditorID>
    <ProductionDesignerID>000000</ProductionDesignerID>
    <LocationSoundID>000000</LocationSoundID>
    <PostSoundID>000000</PostSoundID>
</metadata>
"@

Here is my transform

这是我的转变

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes"/>

 <xsl:template match="metadata">
    <xsl:copy>
    <xsl:copy-of select="LOGLINE"/>
    <xsl:copy-of select="YearVideoMade"/>
    <xsl:copy-of select="LevelOfStudy"/>
    <xsl:copy-of select="SYNOPSIS"/>
    <xsl:copy-of select="Director"/>
    <xsl:copy-of select="DirectorID"/>
    <xsl:copy-of select="Writer"/>
    <xsl:copy-of select="WriterID"/>
    <xsl:copy-of select="Producer"/>
    <xsl:copy-of select="ProducerID"/>
    <xsl:copy-of select="Cinematographer"/>
    <xsl:copy-of select="CinematographerID"/>
    <xsl:copy-of select="Editor"/>
    <xsl:copy-of select="EditorID"/>
    <xsl:copy-of select="ProductionDesigner"/>
    <xsl:copy-of select="ProductionDesignerID"/>
    <xsl:copy-of select="LocationSound"/>
    <xsl:copy-of select="LocationSoundID"/>
    <xsl:copy-of select="PostSound"/>
    <xsl:copy-of select="PostSoundID"/>
    <xsl:copy-of select="Composer"/>
    <xsl:copy-of select="ComposerID"/>
    <xsl:copy-of select="Screenmusic"/>
    <xsl:copy-of select="ScreenMusicID"/>
    <xsl:copy-of select="FESTIVALSANDAWARDS"/>
    <xsl:copy-of select="AreaOfSpecialisation"/>
    <xsl:copy-of select="RestrictedVideo"/>
    <xsl:copy-of select="RestrictedVideoText"/>
    <xsl:copy-of select="AFTRSSTUDENTKEYCREATIVECREW"/>
    </xsl:copy>
 </xsl:template>
</xsl:stylesheet>

PS.. If I do write the transformed content to a file, then the transform works as expected so I know the stylesheet does what is asked of it

PS ..如果我将转换后的内容写入文件,那么转换按预期工作,所以我知道样式表做了什么问题

Regards

问候

Angus

安格斯

Additional information in light of Mathais R Jensen's response:

根据Mathais R Jensen的回应补充资料:

The XML to be transformed is obtained from a web service call and extracted from the returned XML package. The XML extract is html encoded, so I decode it with System.Web.HttpUtility.decode() then cast the resultant string to XML-->XMl Node --> XPathDocument --> XPathNavigator

要转换的XML是从Web服务调用获得的,并从返回的XML包中提取。 XML提取是html编码的,所以我使用System.Web.HttpUtility.decode()解码它,然后将结果字符串转换为XML - > XMl Node - > XPathDocument - > XPathNavigator

 [xml] $metaDstr = [System.Web.HttpUtility]::HtmlDecode($metaD)
 $nodeReader = New-Object System.Xml.XmlNodeReader($metaDStr)
 $XPD = New-Object System.Xml.XPath.XPathDocument($nodeReader)
 $XPreader = $XPD.CreateNavigator()

At this point I have been inserting $XPreader into a node of another document generated by the XmlTextWriter class using the XmlTextWriter.WriteNode() method

此时我已经使用XmlTextWriter.WriteNode()方法将$ XPreader插入到XmlTextWriter类生成的另一个文档的节点中

however I need to transform the extracted XML to get the nodes in the correct order for ingestion into another system.

但是,我需要转换提取的XML,以便以正确的顺序获取节点,以便将其提取到另一个系统中。

If I call the transform method on the $XPreader I get the error message

如果我在$ XPreader上调用transform方法,我会收到错误消息

Exception calling "Transform" with "2" argument(s): "The specified path, file name, or 
both are too long. The fully qualified file name must be less than 260 characters, and 
the directory name must be less than 248 characters."   

The transform is looking for a file input.

转换正在寻找文件输入。

1 个解决方案

#1


3  

Generate the XmlWriter from a new XmlDocument:

从新的XmlDocument生成XmlWriter:

# Create new document
$NewDoc = New-Object xml

# Create XmlWriter from new document
$NewDocWriter = $NewDoc.CreateNavigator().AppendChild()

# Load the XSL
$Xslt = New-Object System.Xml.Xsl.XslCompiledTransform
$Xslt.Load("C:\dev\transform.xsl")

# Transform, output to XmlWriter
$Xslt.Transform((New-Object System.Xml.XmlNodeReader $mydoc),$NewDocWriter)

# Flush and close the writer
$NewDocWriter.Flush()
$NewDocWriter.Close()

$NewDoc now contains the transformed XML document

$ NewDoc现在包含转换后的XML文档

#1


3  

Generate the XmlWriter from a new XmlDocument:

从新的XmlDocument生成XmlWriter:

# Create new document
$NewDoc = New-Object xml

# Create XmlWriter from new document
$NewDocWriter = $NewDoc.CreateNavigator().AppendChild()

# Load the XSL
$Xslt = New-Object System.Xml.Xsl.XslCompiledTransform
$Xslt.Load("C:\dev\transform.xsl")

# Transform, output to XmlWriter
$Xslt.Transform((New-Object System.Xml.XmlNodeReader $mydoc),$NewDocWriter)

# Flush and close the writer
$NewDocWriter.Flush()
$NewDocWriter.Close()

$NewDoc now contains the transformed XML document

$ NewDoc现在包含转换后的XML文档