0

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

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

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.

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

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.

Reference is here: Reference Docs MSDN XslCompiledTransform Class

Here is my xml as a

$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

Regards

Angus

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

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] $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

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

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

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 Answer 1

3

Generate the XmlWriter from a new XmlDocument:

# 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

Sign up to request clarification or add additional context in comments.

8 Comments

Thanks @mathias I have done this but I get an interesting error. Exception calling "Transform" with "2" argument(s): "Could not find file 'C:\Users\adenton\System.Xml.XmlNodeReader'." i think I need to post more code as I have used some shorthand here on how I obtain my input XML
@GusD If $mydoc is an XML document (loaded from the contents you posted), and you use my code as-is, it should work. Feel free to update your question if anything is missing (your XSLT example is missing its declaration and the opening stylesheet tag btw)
Hi @Mathias additional information and context posted I changed the argument for the transform and got a different error from the one above. However the transform is still essentially looking for a file though.
@GusD I see. Skip the two last steps and pass the $nodeReader as the first argument to Transform()
this produces the following error Exception calling "Transform" with "2" argument(s): "Could not find file 'C:\Users\{me}\System.Xml.XmlNodeReader'."
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.