how to append child to element using smooks groovy - groovy

I am trying to use Smooks with Groovy to appendChild() to elements. So far I've been unable to do so.
Sample input file
<?xml version="1.0"?>
<orders>
<order res="0">
<header>
<date>Wed Nov 27 13:45:28 EST 2013</date>
<customer number="9404089839">Harish Nanda M</customer>
</header>
<orderitems>
<orderitem>
<product>007</product>
<quantity>7</quantity>
<price>7.90</price>
</orderitem>
<orderitem>
<product>005</product>
<quantity>3</quantity>
<price>7.20</price>
</orderitem>
</orderitems>
</order>
<order res="0">
<header>
<date>Wed Nov 27 13:45:28 EST 2013</date>
<customer number="2036139296">Sandesh G</customer>
</header>
<orderitems>
<orderitem>
<product>0023</product>
<quantity>87</quantity>
<price>57.90</price>
</orderitem>
<orderitem>
<product>005</product>
<quantity>3</quantity>
<price>7.20</price>
</orderitem>
</orderitems>
</order>
</orders>
Smooks config file
<?xml version="1.0"?>
<smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd" xmlns:core="http://www.milyn.org/xsd/smooks/smooks-core-1.3.xsd" xmlns:g="http://www.milyn.org/xsd/smooks/groovy-1.1.xsd">
<core:filterSettings type="SAX"/>
<g:groovy executeOnElement="order">
<g:imports>
import org.milyn.xml.DomUtils;
import org.milyn.javabean.context.BeanContext;
import org.milyn.javabean.repository.BeanRepository;
import org.w3c.dom.*;
import groovy.xml.dom.DOMCategory;
import groovy.xml.dom.DOMUtil;
import groovy.xml.DOMBuilder;
import groovy.util.XmlSlurper;
</g:imports>
<g:script>
<!-- javax.xml.transform.dom.DOMSource source = new javax.xml.transform.dom.DOMSource(element);
javax.xml.transform.Transformer transformer = javax.xml.transform.TransformerFactory.newInstance().newTransformer();
javax.xml.transform.stream.StreamResult result = new
javax.xml.transform.stream.StreamResult(new java.io.StringWriter());
transformer.transform(source, result); String ss =
result.getWriter().toString(); def ord = new
XmlSlurper().parseText(ss) //ord.xxxx = "2222"; println
ord.orderitems.orderitem.product.text()*.toInteger().sum();
element.appendChild("res"); //element['#res'] = element.'#res'.toInteger() +
ord.orderitems.orderitem.product.text()*.toInteger().sum();
writeFragment(element);
-->
</g:script>
</g:groovy>
</smooks-resource-list>

Related

Add custom headers to SOAP request using zeep.Client Python

I have problems creating and adding custom headers to SOAP header. If I write a RAW request it works, but I want to use zeep library in Python3
I tried to add theese headers
header = xsd.Element(
'headerMDMPeticio',xsd.ComplexType([
xsd.Element('idSistemaOrigen',xsd.String()),
xsd.Element(
'headerMidominio',xsd.ComplexType([
xsd.Element('usuariConnectat',xsd.String()),
xsd.Element('rolUsuariConnectat',xsd.String())
])
)
])
)
header_value = header(headerMidominio={'usuariConnectat':'user','rolUsuariConnectat':'roleExample'})
extracted from theese book https://buildmedia.readthedocs.org/media/pdf/python-zeep/master/python-zeep.pdf (page 18)
Here is the python code for generate XML that I'm using
from django.shortcuts import render
from django.utils import timezone
from django.conf import settings
from django.contrib.auth.mixins import LoginRequiredMixin,PermissionRequiredMixin
from django.views.generic import ListView, DetailView, CreateView, UpdateView, DeleteView, TemplateView, FormView
from zeep import Client, xsd
from zeep.wsse.username import UsernameToken
from lxml import etree
from .models import MDMRelCodiProjecte
def codiprojecte_list(request):
codis = MDMRelCodiProjecte.objects.filter(data_esborrat__isnull=True).order_by('data_modificat')
#Consultamos al servicio SOAP
url_service = "https://services.dev.midominio.edu/soa/extern/SOAP12/MDMCodisProjectes/v01_00"
url_wsdl = url_service+"/?wsdl"
soapClient = Client(url_wsdl,wsse=UsernameToken('developer_user','miPasswordEnTextoPlano'))
soapClient.service._binding_options['address'] = url_service # En el WSDL viene con una URL incorrecta --> ponemos la correcta!
id_service = '100045976'
soapDataUserPass = {'Username':'developer_user','Password':'miPasswordEnTextoPlano'}
node = soapClient.create_message(soapClient.service, 'consultarCodiProjecteMDM',id_service)
print (node)
print (etree.tostring(node,pretty_print=True))
#print(soapClient.service.consultarCodiProjecteMDM(id_service,soapDataUsosDada))
return render(request, 'codi_projecte/codiprojecte_list.html', {'codis':codis})
Expected (extracted from SOAP UI), focus on v01:headerMDMPeticio and children of this node. Inside body I also need to ADD v012:usosDada to request.
Accept-Encoding: gzip,deflate
Content-Type: application/soap+xml;charset=UTF-8;action="http://services.dev.midominio.edu/soa/servei/CodisProjectesMDM/v01_00/consultarCodiProjecteMDMInput"
Content-Length: 1811
Host: services.dev.midominio.edu
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:v01="http://midominio.edu/soa/esquema/ElementsComunsMDM/v01_00" xmlns:v011="http://midominio.edu/soa/esquema/ElementsComuns/v01_01" xmlns:v012="http://midominio.edu/soa/servei/MDMCodisProjectes/v01_00">
<soap:Header>
<wsse:Security soap:mustUnderstand="true" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:UsernameToken wsu:Id="UsernameToken-6e6f6d657365617363757472656e6f6F">
<wsse:Username>developer_user</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">miPasswordEnTextoPlano</wsse:Password>
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">rndomDataHash+rndomtxt==</wsse:Nonce>
<wsu:Created>2019-06-05T08:20:45.644Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
<v01:headerMDMPeticio>
<v01:idSistemaOrigen>1</v01:idSistemaOrigen>
<v01:headerMidominio>
<v011:usuariConnectat>usuarioPlataforma</v011:usuariConnectat>
<v011:rolUsuariConnectat>pepitoPalote</v011:rolUsuariConnectat>
</v01:headerMidominio>
</v01:headerMDMPeticio>
</soap:Header>
<soap:Body>
<v012:consultarCodiProjecteMDMInput>
<v012:idMDM>100045976</v012:idMDM>
<v012:usosDada>
<v01:arrayUsosDeDadaItem>
<v01:tipus>Prova persona</v01:tipus>
</v01:arrayUsosDeDadaItem>
</v012:usosDada>
</v012:consultarCodiProjecteMDMInput>
</soap:Body>
</soap:Envelope
And this is that I generate with my Python code
<soap-env:Envelope xmlns:soap-env="http://www.w3.org/2003/05/soap-envelope">
<soap-env:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken>
<wsse:Username>developer_user</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">miPasswordEnTextoPlano</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soap-env:Header>
<soap-env:Body>
<ns0:consultarCodiProjecteMDMInput xmlns:ns0="https://services.dev.midominio.edu/soa/servei/MDMCodisProjectes/v01_00">
<ns0:idMDM>100045976</ns0:idMDM>
</ns0:consultarCodiProjecteMDMInput>
</soap-env:Body>
</soap-env:Envelope>
Zeep requires that you define your headers in the special kwarg _soapheaders, like so:
from zeep import Client
wsdl = 'http://localhost/services/Assets?wsdl'
client = Client(wsdl)
request_data = {
"InterplayPathURI" : "interplay://TGAvid/Projects",
"SearchGroup" : {
"Operator" : "OR",
"AttributeCondition" : {
"Condition" : "EQUALS",
"Attribute" :
{"Group" : "SYSTEM",
"Name": "Type",
"_value_1": "masterclip"},
},
},
"MaxResults" : "500",
}
header_value = {
"credentialsHeader" : {
"Username" : "administrator",
"Password" : "Avid123"
}
}
result = client.service.Search(**request_data, _soapheaders=header_value)

libxmljs: how to use xinclude?

I try to use libxmljs with nodejs.
In my sample I want to use the xi:include.
<ord:order xmlns:ord="http://example.org/ord"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://example.org/ord chapter04ord1.xsd"
xmlns:xi="http://www.w3.org/2001/XInclude">
<number>123ABBCC123</number>
<customer>
<name>Priscilla Walmsley</name>
<number>15466</number>
</customer>
<items>
<xi:include href="/Users/mar/ws_e/libxml/test/resources/chapter5prod.xml" />
</items>
</ord:order>
include File:
<ord:product xmlns:ord="http://example.org/ord"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://example.org/ord chapter04ord1.xsd">
<number>557</number>
<name>Short-Sleeved Linen Blouse</name>
<size system="US-DRESS">10</size>
<color value="blue"/>
</ord:product>
This is my code:
var xsdDoc = libxml.parseXml(schemaSource);
var xmlDocValid = libxml.parseXml(docSource);
var xmlDocInvalid = libxml.parseXml(xml_invalid);
xmlDocValid.validate(xsdDoc);
console.dir(xmlDocValid);
console.dir(xmlDocValid.validationErrors);
Then I get the error:
Document {
errors: [],
validationErrors:
[ { Error: Element '{http://www.w3.org/2001/XInclude}include': This element is not expected. Expected is ( product ).
So my question is how to use the x:include right at libxmljs?
Kind regards
Markus

OCMod not finding blocks of code

What is up with OCMod? It will not find a block of code [that I need to replace]
Here is what I have in my mod:
<?xml version="1.0" encoding="utf-8"?>
<modification>
<file path="catalog/controller/information/information.php">
<operation>
<search><![CDATA[$data['breadcrumbs'] = array();]]></search>
<add position="after"><![CDATA[$template = 'newproducts.tpl';]]></add>
</operation>
<operation>
<search>
<![CDATA[
if (file_exists(DIR_TEMPLATE . $this->config->get('config_template') . '/template/information/information.tpl')) {
$this->response->setOutput($this->load->view($this->config->get('config_template') . '/template/information/information.tpl', $data));
} else {
$this->response->setOutput($this->load->view('default/template/information/information.tpl', $data));
}
]]>
</search>
<add position="after"><![CDATA[echo 'booooooger';]]></add>
</operation>
</file>
</modification>
the First operation works just fine, the second does not find the block of code in the search [and it is there exactly - I've synced and diffed the files it IS there] Here is the error:
FILE: catalog/controller/information/information.php
CODE: $data['breadcrumbs'] = array();
LINE: 8
CODE: if (file_exists(DIR_TEMPLATE . $this->config->get('config_template') . '/template/information/information.tpl')) {
$this->response->setOutput($this->load->view($this->config->get('config_template') . '/template/information/information.tpl', $data));
} else {
$this->response->setOutput($this->load->view('default/template/information/information.tpl', $data));
}
NOT FOUND!
I've tried the search with the trim attribute set to both true and false... no luck.
How do I get this to work?
I suggest to use single line search, if you want to search multiline then you need to use regex or more.
<operation>
<search>
<![CDATA[
$this->response->setOutput($this->load->view('default/template/information/information.tpl', $data));
]]>
</search>
<add position="after" offset="1">
<![CDATA[
echo 'booooooger';
]]>
</add>
</operation>

Read TLV encoded data on JavaCard Classic

I'd like to read TLV encoded certificates on a Java Card (NXP JCOP J3D081, JCOP version 2.4.2, Java Card version 3.0.1 Classic).
The cap file is created successfully, but when I try to install it on the card I get an gpshell error:
load() returns 0x80206A80 (6A80: Wrong data / Incorrect values in command data.)
I use the jars from JCDK 3.0.3 and this usually works with stuff like elliptic curves etc. What could be different with the TLV stuff?
The applet code used (installs fine when not using the BERTLV stuff):
package org.thomas;
import javacard.framework.APDU;
import javacard.framework.Applet;
import javacard.framework.ISO7816;
import javacard.framework.ISOException;
import javacard.framework.Util;
import javacardx.framework.tlv.BERTLV;
import javacardx.framework.tlv.ConstructedBERTLV;
public class TlvApplet extends Applet {
private ConstructedBERTLV certificate;
byte[] certificateLength = new byte[2];
/**
* TlvApplet constructor
*
* #constructor
*/
private TlvApplet() {
// Register with the JCRE
register();
}
/**
* Installs applet
*
* #param bArray
* the array containing installation parameters
* #param bOffset
* the starting offset in bArray
* #param bLength
* the length in bytes of the parameter data in bArray
*/
public static void install(byte[] bArray, short bOffset, byte bLength) {
new TlvApplet();
}
public void process(APDU apdu) throws ISOException {
byte buffer[] = apdu.getBuffer();
short incomingLength = apdu.setIncomingAndReceive();
certificate = (ConstructedBERTLV) BERTLV.getInstance(buffer,
ISO7816.OFFSET_CDATA, incomingLength);
certificateLength[0] = (byte) (certificate.size() & 0xff);
certificateLength[1] = (byte) ((certificate.size() >> 8) & 0xff);
Util.arrayCopyNonAtomic(certificateLength, (short) 0, buffer,
ISO7816.OFFSET_CDATA, (short) 2);
}
}
I create the cap file by using the following ant build.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<project default="convert" name="Create JC 3 applet" basedir=".">
<property environment="env" />
<!-- Include properties in the build.properties file -->
<property file="build.properties" />
<!-- Build specific properties -->
<property name="source.path" location="${basedir}/${source.folder}" />
<property name="jcdk.libs" location="${basedir}/${jcdk.basefolder}/${jcdk.subfolder.libs}" />
<property name="jcdk.apiexports" location="${basedir}/${jcdk.basefolder}/${jcdk.subfolder.apiexportfiles}" />
<property name="target.path.classes"
location="${basedir}/${target.basefolder}/${target.subfolder.classes}" />
<property name="target.path.cap"
location="${basedir}/${target.basefolder}/${target.subfolder.applet}" />
<!-- set the classpath for the tasks and the API, include all jar files -->
<path id="classpath" description="Sets the classpath to Java Card API and tools">
<fileset dir="${jcdk.libs}">
<include name="*.jar" />
</fileset>
</path>
<!-- set the export path to the Java Card export files -->
<path id="export" description="set the export file path">
<fileset dir="${jcdk.apiexports}">
<include name="**/*.exp" />
</fileset>
<pathelement path="${jcdk.apiexports}" />
<pathelement path="${target.path.classes}" />
</path>
<path id="capexport" description="set the export file for the cap path">
<fileset dir="${jcdk.apiexports}">
<include name="**/*.exp" />
</fileset>
<pathelement path="${jcdk.apiexports}" />
</path>
<!-- Definitions for tasks for Java Card tools -->
<taskdef name="apdu" classname="com.sun.javacard.ant.tasks.APDUToolTask" classpathref="classpath" />
<taskdef name="capgen" classname="com.sun.javacard.ant.tasks.CapgenTask" classpathref="classpath" />
<taskdef name="convert" classname="com.sun.javacard.ant.tasks.ConverterTask" classpathref="classpath" />
<taskdef name="verifyexport" classname="com.sun.javacard.ant.tasks.VerifyExpTask" classpathref="classpath" />
<taskdef name="verifycap" classname="com.sun.javacard.ant.tasks.VerifyCapTask" classpathref="classpath" />
<taskdef name="verifyrevision" classname="com.sun.javacard.ant.tasks.VerifyRevTask" classpathref="classpath" />
<typedef name="appletnameaid" classname="com.sun.javacard.ant.types.AppletNameAID" classpathref="classpath" />
<typedef name="jcainputfile" classname="com.sun.javacard.ant.types.JCAInputFile" classpathref="classpath" />
<typedef name="scriptgen" classname="com.sun.javacard.ant.tasks.ScriptgenTask" classpathref="classpath" />
<target name="init">
<mkdir dir="${target.path.classes}" />
</target>
<target name="clean">
<delete dir="${target.path.classes}" />
</target>
<target name="compile" depends="init" description="Compile source code to class files">
<javac debug="${javac.debug}"
optimize="${javac.optimize}"
srcdir="${source.path}"
destdir="${target.path.classes}"
source="${javac.version.source}"
target="${javac.version.target}">
<classpath refid="classpath" />
</javac>
</target>
<target name="convert" depends="compile" description="Convert class files to cap files">
<convert packagename="${package.name}"
packageaid="${package.aid}"
majorminorversion="${applet.version}"
classdir="${target.path.classes}"
outputdirectory="${target.path.cap}"
jca="${cap.creation.jca}"
exp="${cap.creation.exp}"
cap="true"
debug="${cap.creation.debug}" verbose="${cap.creation.verbose}"
noverify="${cap.creation.noverify}">
<appletnameaid aid="${applet.aid}" appletname="${applet.name}" />
<exportpath refid="capexport" />
<classpath refid="classpath" />
</convert>
</target>
<target name="all" depends="clean, convert" />
</project>
The build.properties used:
# Source folder
source.folder = src/org/thomas
# Java Card Development Kit folders
jcdk.basefolder = lib/javaCardKit303
jcdk.subfolder.apiexportfiles = api_export_files
jcdk.subfolder.libs = lib
# Target folders (will be created, no need to adapt)
target.basefolder = target
target.subfolder.classes = classes
target.subfolder.applet = applet
# Applet properties
package.aid = 0x41:0x41:0x41:0x41:0x41:0x41:0x41:0x41:0x41:0x42
package.name = org.thomas
applet.aid = 0x41:0x41:0x41:0x41:0x41:0x41:0x41:0x41:0x41:0x42:0x42
applet.name = TlvApplet
applet.version = 1.0
# Java class compiler options
javac.debug = no
javac.optimize = no
javac.version.source = 1.5
javac.version.target = 1.5
# CAP file creation options
cap.creation.verbose = false
cap.creation.noverify = false
cap.creation.debug = false
cap.creation.jca = false
cap.creation.exp = false
So suspected the cap to be compiled with the api_connected.jar, but removing the file from kit, didn't change anything.
Any help would be appreciated. Thanks in advance, Thomas
The card simply does not support the TLV classes of the java card API. The JC API is just a recommendation but the card manufacturer may choose to implement a subset of it.
In general anything in javacardx is optional (hence the x at the end). The API methods in javacard must be implemented though. Even for javacard packages and classes not all functionality may be available at runtime. For instance, cryptographic algorithms may not be present.

Parse XML using Groovy: How do I keep the CDATA when parsing a XML file

Using Groovy 2.0.5 JVM 1.6.0_31, I have created a script that takes an existing XML-file as input
def root = new XmlParser().parse(new File('filename'))
I parse the file and replaces certain attributes like this
root.Settings.Setting.each {
if (it.'#NAME' =~ 'CASEID_SEQUENCE_SIZE') {
it.'#VALUE' = '100'
And then at the end writes the changes to a new file like this
def outputfile = new File( levelConfig.RESULTFILE )
new XmlNodePrinter(new PrintWriter(outputfile)).print(root)
All this is fine, no problem, except when the XML has CDATA, like this
<HandlerURL>
<![CDATA[admin/MainWindow.jsp]]>
</HandlerURL>
the result is then
<HandlerURL>
admin/MainWindow.jsp
</HandlerURL>
Question is
How can I get my script to not do anything with the CDATA?
Found you can do:
import groovy.xml.*
import groovy.xml.dom.DOMCategory
def xml = '''<root>
| <Settings>
| <Setting name="CASEID_SEQUENCE_SIZE">
| <HandlerURL>
| <![CDATA[ admin/MainWindow.jsp ]]>
| </HandlerURL>
| </Setting>
| <Setting name="SOMETHING_ELSE">
| <HandlerURL>
| <![CDATA[ admin/MainWindow.jsp ]]>
| </HandlerURL>
| </Setting>
| </Settings>
|</root>'''.stripMargin()
def document = DOMBuilder.parse( new StringReader( xml ) )
def root = document.documentElement
use(DOMCategory) {
root.Settings.Setting.each {
if( it.'#name' == 'CASEID_SEQUENCE_SIZE' ) {
it[ '#value' ] = 100
}
}
}
def result = XmlUtil.serialize( root )
println result
To get the output:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<Settings>
<Setting name="CASEID_SEQUENCE_SIZE" value="100">
<HandlerURL>
<![CDATA[ admin/MainWindow.jsp ]]>
</HandlerURL>
</Setting>
<Setting name="SOMETHING_ELSE">
<HandlerURL>
<![CDATA[ admin/MainWindow.jsp ]]>
</HandlerURL>
</Setting>
</Settings>
</root>

Resources