Copy contents of one node to another XSLT - xslt-1.0

Using XLST 1.0 I want to copy any nodes called INSTRUCTIONS, and the child elements, to another location in the tree.
There can be more than one INSTRUCTIONS containers under WO.
/my:TRANS/my:DE/my:CO/my:RE/my:PR/my:WO
The target location of the INSTRUCTIONS is under PRSI and PRSI does not exist in the original source.
/my:TRANS/my:DE/my:CO/my:RE/my:PR/my:PRSI
Please advise.
Here is some example input. I'm omitting the namespace:
<trans>
<de>
<co>
<re>
<pr>
<wo>
<INSTRUCTIONS>
<category>1</category>
<description>abc</description>
</INSTRUCTIONS>
<INSTRUCTIONS>
<category>2</category>
<description>xyz</description>
</INSTRUCTIONS>
</wo>
</pr>
</re>
</co>
</de>
</trans>
Here is expected output. I'm omitting the namespace:
<trans>
<de>
<co>
<re>
<pr>
<PRSI>
<INSTRUCTIONS>
<category>1</category>
<description>abc</description>
</INSTRUCTIONS>
<INSTRUCTIONS>
<category>2</category>
<description>xyz</description>
</INSTRUCTIONS>
</PRSI>
</pr>
</re>
</co>
</de>
</trans>
This is what I have so far.
<xsl:template match="//my:TRANS/my:DE/my:CO/my:RE/my:PR/my:WO">
<my:PRSI>
<xsl:copy>
<xsl:copy-of select="#* | node()" />
<xsl:apply-templates select="*" />
</xsl:copy>
</my:PRSI>
</xsl:template>

Related

failed to schedual xaction file for run PDI job

I want to run my Pentaho-data-integration job with xaction file.
my job(schedualeJob.kjb) has one transformation(repository2.ktr)( without any schedule).
the contetnt of my schedule.xaction file is:
<?xml version="1.0" encoding="UTF-8"?>
<action-sequence>
<title>My scheduled job</title>
<version>1</version>
<logging-level>ERROR</logging-level>
<documentation>
<author>mzy</author>
<description>Sequence for running daily job.</description>
<help/>
<result-type/>
<icon/>
</documentation>
<inputs>
</inputs>
<outputs>
<logResult type="string">
<destinations>
<response>content</response>
</destinations>
</logResult>
</outputs>
<resources>
<job-file>
<solution-file>
<location>schedualeJob.kjb</location>
<mime-type>text/xml</mime-type>
</solution-file>
</job-file>
</resources>
<actions>
<action-definition>
<component-name>KettleComponent</component-name>
<action-type>Pentaho Data Integration Job</action-type>
<action-inputs>
</action-inputs>
<action-resources>
<job-file type="resource"/>
</action-resources>
<action-outputs>
<kettle-execution-log type="string" mapping="logResult"/>
<kettle-execution-status type="string" mapping="statusResult"/>
</action-outputs>
<component-definition>
<kettle-logging-level><![CDATA[info]]></kettle-logging-level>
</component-definition>
</action-definition>
</actions>
</action-sequence>
I uploaded all of these 3 file in my Pentaho cde repository(beside of my report).
and set schedule for schedule.xaction file from pentaho cde. but the schedule does not run correctly. any body can help me?

Need help selecting values from XML file using SQL xQuery

Help!
I have an XML log file generated by WinSCP, and I'd like to trigger an alert based on it's contents. I have no control on how the XML is formatted.
I'm trying to use xQuery to read the values, but no luck. All I get are column heading with 0 rows. I've also tried OPENXML and VBA ImportXML, but both methods return nulls.
DECLARE #XML XML =
'<?xml version="1.0" encoding="UTF-8"?>
<session xmlns="http://winscp.net/schema/session/1.0" name="ftpuser#ftphost.com" start="2017-11-09T18:00:09.051Z">
<upload>
<filename value="e:\MyUploadFile.txt" />
<destination value="/HostFolder/MyUploadFile.txt" />
<result success="true" />
</upload>
<touch>
<filename value="/HostFolder/MyUploadFile.txt" />
<modification value="2017-11-09T18:00:08.000Z" />
<result success="true" />
</touch>
</session>
'
SELECT
Sess.Upload.value('../filename[1]','varchar(250)') [Filename]
,Sess.Upload.value('../destination[1]','varchar(250)') [Destination]
,Sess.Upload.value('../result[1]','varchar(250)') [Result]
FROM
#XML.nodes ('/session/upload') AS Sess(Upload)
Did you manipulate your XML? There is a quote missing after .../session/1.0 and name in the second line.
This XML has a default namespace which you have to declare. I do not know, what you expect as output, but my magic crystal ball tells me, that it might be something like this:
DECLARE #XML XML =
'<?xml version="1.0" encoding="UTF-8"?>
<session xmlns="http://winscp.net/schema/session/1.0" name="ftpuser#ftphost.com" start="2017-11-09T18:00:09.051Z">
<upload>
<filename value="e:\MyUploadFile.txt" />
<destination value="/HostFolder/MyUploadFile.txt" />
<result success="true" />
</upload>
<touch>
<filename value="/HostFolder/MyUploadFile.txt" />
<modification value="2017-11-09T18:00:08.000Z" />
<result success="true" />
</touch>
</session>
';
WITH XMLNAMESPACES(DEFAULT 'http://winscp.net/schema/session/1.0')
SELECT
Sess.Upload.value('local-name(.)','nvarchar(max)') AS FileAction
,Sess.Upload.value('(filename/#value)[1]','varchar(250)') [Filename]
,Sess.Upload.value('(destination/#value)[1]','varchar(250)') [Destination]
,Sess.Upload.value('(modification/#value)[1]','varchar(250)') [Modification]
,Sess.Upload.value('(result/#success)[1]','varchar(250)') [Result]
FROM #XML.nodes ('/session/*') AS Sess(Upload);
It seems that you have omitted double-quote at the end of the namespace, so your XML is effectively invalid.
You have to declare the namespace. Like:
WITH XMLNAMESPACES (DEFAULT 'http://winscp.net/schema/session/1.0')
../ is wrong. It should be ./.

Exclude Parent entire node if child has some specific string

I have the following XML
<root>
<Package1>
<Name> Test </Name>
<Sales_Channel ID=123>
<Name>Online</Name>
</Sales_Channel>
<Sales_Channel ID=234>
<Name>Direct</Name>
</Sales_Channel>
</Package1>
<Package2>
<Name> Test </Name>
<Sales_Channel ID=234>
<Name>Direct</Name>
</Sales_Channel>
</Package2>
<Package3>
<Name> Test </Name>
<Sales_Channel ID=123>
<Name>Online</Name>
</Sales_Channel>
</Package3>
</root>
I would like to exclude those packages which is tagged with only
<Sales_Channel ID=123>
<Name>Online</Name>
</Sales_Channel>
So my final output should look like below:
<root>
<Package1>
<Name> Test </Name>
<Sales_Channel ID=123>
<Name>Online</Name>
</Sales_Channel>
<Sales_Channel ID=234>
<Name>Direct</Name>
</Sales_Channel>
</Package1>
<Package2>
<Name> Test </Name>
<Sales_Channel ID=234>
<Name>Direct</Name>
</Sales_Channel>
</Package2>
</root>
This may work for you. It works in Microsoft 1.0. I did have to add quotes around your ID values to get it to work there.
<!-- Suppress. -->
<xsl:template match="*[contains(local-name(), 'Package') and .//Sales_Channel[#ID='123'] and not(.//Sales_Channel[#ID!='123'])]"/>
<!-- Identity template -->
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>

Converting Complex XML to CSV

I have some (complex to me) XML code that I need to convert into CSV, I need absolutely every value added to the CSV for every submission, I have tried a few basic things however I cant get past the deep nesting and the different structures of this file.
Could someone please help me with a powershell script that would, I have started but cannot get the output of all data out I only get Canvas Results
Submissions.xml To large to post here (102KB)
$d=([xml](gc submissions.xml)).CANVASRESULTS | % {
foreach ($i in $_.CANVASRESULTS) {
$o = New-Object Object
Add-Member -InputObject $o -MemberType NoteProperty -Name Submissions -Value $_.Submission
Add-Member -InputObject $o -MemberType NoteProperty -Name Submission -Value $i
$o
}
}
$d | ConvertTo-Csv -NoTypeInformation -Delimiter ","
Anytime a complex XML has deeply nested structures and you require migration into a flat file format (i.e., txt, csv, xlsx, sql), consider using XSLT to simplify your XML format. As information, XSLT is a declarative, special-purpose programming language used to style, re-format, re-structure XML/HTML and other SGML markup documents for various end-use purposes. Aside - SQL is also a declarative, special-purpose programming language.
For most softwares to import XML into flat file formats in two dimensions of rows and columns, XML files must follow repeating elements (i.e., rows/records) with one level of children for columns/fields:
<data>
<row>
<column1>value</column1>
<column1>value</column1>
<column1>value</column1>
...
</row>
<row>
...
</data>
Nearly every programming language maintains an XSLT processor including PowerShell, Java, C#, Perl, PHP, Python, SAS, even VBA with your everyday MS Excel. For your complex XML, below is an example XSLT stylesheet with following output. Do note I manually create nodes based on values from original XML:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="CanvasResult">
<Data>
<xsl:for-each select="//Responses">
<Submission>
<Fitter><xsl:value-of select="Response[contains(Label, 'Fitter Name')]/Value"/></Fitter>
<Date><xsl:value-of select="Response[Label='Date']/Value"/></Date>
<Time><xsl:value-of select="Response[Label='Time']/Value"/></Time>
<Client><xsl:value-of select="Response[Label='Client']/Value"/></Client>
<Machine><xsl:value-of select="Response[Label='Machine']/Value"/></Machine>
<Hours><xsl:value-of select="Response[Label='Hours']/Value"/></Hours>
<Signature><xsl:value-of select="Response[Label='Signature']/Value"/></Signature>
<SubmissionDate><xsl:value-of select="Response[Label='Submission Date:']/Value"/></SubmissionDate>
<SubmissionTime><xsl:value-of select="Response[Label='Submission Time:']/Value"/></SubmissionTime>
<Customer><xsl:value-of select="Response[Label='Customer:']/Value"/></Customer>
<PlantLocation><xsl:value-of select="Response[Label='Plant Location']/Value"/></PlantLocation>
<PlantType><xsl:value-of select="Response[Label='Plant Type:']/Value"/></PlantType>
<PlantID><xsl:value-of select="Response[Label='Plant ID:']/Value"/></PlantID>
<PlantHours><xsl:value-of select="Response[Label='Plant Hours:']/Value"/></PlantHours>
<RegoExpiryDate><xsl:value-of select="Response[Label='Rego Expiry Date:']/Value"/></RegoExpiryDate>
<Comments><xsl:value-of select="Response[Label='Comments:']/Value"/></Comments>
</Submission>
</xsl:for-each>
</Data>
</xsl:template>
</xsl:stylesheet>
Output
<?xml version='1.0' encoding='UTF-8'?>
<Data>
...
<Submission>
<Fitter>Damian Stewart</Fitter>
<Date/>
<Time/>
<Client/>
<Machine/>
<Hours/>
<Signature/>
<SubmissionDate>28/09/2015</SubmissionDate>
<SubmissionTime>16:30</SubmissionTime>
<Customer>Dicks Diesels</Customer>
<PlantLocation/>
<PlantType>Dozer</PlantType>
<PlantID>DZ09</PlantID>
<PlantHours>2213.6</PlantHours>
<RegoExpiryDate>05/03/2016</RegoExpiryDate>
<Comments>Moving tomorrow from Daracon BOP to KCE BOP S6A Dam
Cabbie to operate</Comments>
</Submission>
...
</Data>
From there, you can import the two-dimensional XML into a usable rows/columns format. Below are the same import into an MS Access Database and MS Excel spreadsheet. You will notice gaps in the data due to XML content not populating the created nodes (handled in XSLT). A simple SQL cleanup can render final dataset.
Database Import

How to get first element by XPath in Oracle

In my Oracle db I have records like this one:
<ROOT>
<Event>
<Type>sldkfvjhkljh</Type>
<ID>591252</ID>
</Event>
<Data>
<File>
<Name>1418688.pdf</Name>
<URL>/591252/1418688.pdf</URL>
</File>
<File>
<Name>1418688.xml</Name>
<URL>/591252/1418688.xml</URL>
</File>
</Data>
</ROOT>
I need to extract a value from the first <Name> tag. If I try:
Select xmltype(xml_data).extract('//Name[1]/text()').getStringVal() from MY_TABLE
I get:
1418688.pdf1418688.xml
Why is that and how can I get just 1418688.pdf?
Oracle Version:
Oracle Database 10g Enterprise Edition
Release 10.2.0.4.0 - 64bi
I think that both Name elements are #1 in this doc, because in their nodes they are each first. Try //File[1]/Name/text()