1.smooks选择器
其选择器就是作为一个简单的查找值开始进行工作,XPath表达式时从目标元素向后,而不是从跟元素向后。
2.XPath语法
text()用法
a/b[text()='abc'] a/b[text()=123] text()表达式之后不能再跟其他路径
只有在实现SAXVisitAfter接口的SAXVisitor实现中才支持“text()”
@x用法
a/b[@id=‘abc’]、a/b[@id=123]
text()、@x结合起来使用
a/b[text()='abc' and @id=123],a/b[text()='abc' or @id=123]
元素及属性名称空间
a:order/b:address[@b:city = 'NY'] 需要配置名称空间才可以使用
支持= != > <
索引选择器 a/b[3]
注:c:item[@c:code = '8655']/d:units[text() = 1] text()后不能跟其他选择器,但是@x后可以跟其他选择器
3.名称空间的使用
配置文件
<?xml version="1.0"?>
<smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd" xmlns:jb="http://www.milyn.org/xsd/smooks/javabean-1.4.xsd"
xmlns:core="http://www.milyn.org/xsd/smooks/smooks-core-1.4.xsd">
<core:namespaces>
<core:namespace prefix="a" uri="http://a"/>
<core:namespace prefix="b" uri="http://b"/>
<core:namespace prefix="c" uri="http://c"/>
<core:namespace prefix="d" uri="http://d"/>
</core:namespaces>
<resource-config selector="c:item[@c:code = '8655']/d:units[text() = 1]">
<resource>com.acme.visitors.MyCustomVisitorImpl</resource>
</resource-config>
</smooks-resource-list>
小例子
<?xml version="1.0"?>
<smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd" xmlns:jb="http://www.milyn.org/xsd/smooks/javabean-1.4.xsd"
xmlns:core="http://www.milyn.org/xsd/smooks/smooks-core-1.4.xsd">
<core:namespaces>
<core:namespace prefix="ord" uri="http://acme.com/order" />
</core:namespaces>
</smooks-resource-list>
=================================》smook-config.xml up ---input-message.xml down
<ord:order xmlns:ord="http://acme.com/order">
<ord:header>
<ord:date>Wed Nov 15 13:45:28 EST 2006</ord:date>
<ord:customer number="123123">Joe</ord:customer>
</ord:header>
<ord:order-items>
<ord:order-item>
<ord:product>111</ord:product>
<ord:quantity>2</ord:quantity>
<ord:price>8.90</ord:price>
</ord:order-item>
<ord:order-item>
<ord:product>222</ord:product>
<ord:quantity>7</ord:quantity>
<ord:price>5.20</ord:price>
</ord:order-item>
</ord:order-items>
</ord:order>
4.过滤过程选择
可在配置文件中设置:
<core:filterSettings type="DOM" /> 以此来指定过滤过程处理模型
DOM优点:在代码级别上更容易使用,允许节点遍历。更容易利用脚本和模板引擎来支持使用Dom结构。
DOM缺点:大量消息情况下 不建议使用。
5.Bean上下文
即Smooks.filterSource()操作,可在过滤器进程中访问对象,亦称对象容器。创建的bean都在容器中的beanId。
如果希望在容器结束进程时返回bean上下文对象内容,需在方法中填入对象名称,根据对象.getBean()获取内容。
6.向外界呈现输出
1.结果实例 JavaResult结果类型,用于捕获JavaBean上下文的内容
2.在过滤过程中生成并输出
注:消息流的单个过滤中生成的,不需要多次过滤消息流来生成多个输出结果,因为只会输出其中第一个输出结果
7.Smooks检查执行HTML报告
Smooks支持配置ExecutionContext并且通过HtmlReportGenerator类生成HTML报告
8.终止过滤过程
如何在消息结束前终止Smooks筛选过程。配置:【只适用于SAX过滤器】
<core:Terminate>
<core:terminate onElement="customer" />
<core:terminate onElement="customer" terminateBefore="true" />
9.全局配置
两种类型全局值--默认属性
两种类型全局值--全局参数
全局参数不在根元素上指定,可通过执行上下文配置参数
<params>
<param name="xyz.param1">param1-val</param>
</params>
public void visitAfter(final Element element, final ExecutionContext executionContext) throws SmooksException {
String param1 = executionContext.getConfigParameter("xyz.param1", "defaultValueABC");
....
}
10.过滤器设置
<?xml version="1.0"?>
<smooks-resource-list xmlns="https://www.smooks.org/xsd/smooks-1.2.xsd"
xmlns:core="https://www.smooks.org/xsd/smooks/smooks-core-1.5.xsd">
<core:filterSettings type="SAX" defaultSerialization="true" terminateOnException="true"
readerPoolSize="3" closeSource="true" closeResult="true" rewriteEntities="true" />
<!-- Other visitor configs etc... -->
</smooks-resource-list>
11.组态模块化(<import/> @Tokenname@)
将Smooks配置拆分成多个可重用的配置文件,然后使用<import>元素
<smooks-resource-list xmlns="https://www.smooks.org/xsd/smooks-1.2.xsd">
<import file="bindings/order-binding.xml" />
<import file="templates/order-template.xml" />
</smooks-resource-list>
还可以将另一个模块放进其中一个模块中
<smooks-resource-list xmlns="https://www.smooks.org/xsd/smooks-1.2.xsd">
<import file="bindings/order-binding.xml">
<param name="orderRootElement">order</param>
</import>
</smooks-resource-list>
<!-- Imported parameterized bindings/order-binding.xml configuration... -->
<smooks-resource-list xmlns="https://www.smooks.org/xsd/smooks-1.2.xsd" xmlns:jb="https://www.smooks.org/xsd/smooks/javabean-1.6.xsd">
<jb:bean beanId="order" class="org.acme.Order" createOnElement="@orderRootElement@">
.....
</jb:bean>
</smooks-resource-list>
12.输入数据
默认情况下,从
源消息数据流生成SAX事件流。流读取器是实现XMLReader接口(或SmooksXMLReader接口).
默认情况下,Smooks使用默认的XMLReader(XMLReaderFactory.createXMLReader()),但可以通过配置专用的XMLReader轻松地将其配置为读取非XML数据源 --详情见文档
13.Smooks读取xml
要在默认XML读取器上设置特性,只需从配置中省略类名
<reader>
<features>
<setOn feature="http://a" />
<setOn feature="http://b" />
<setOff feature="http://c" />
<setOff feature="http://d" />
</features>
</reader>
14.Smooks读取json
<?xml version="1.0"?>
<smooks-resource-list xmlns="https://www.smooks.org/xsd/smooks-1.2.xsd" xmlns:json="https://www.smooks.org/xsd/smooks/json-1.3.xsd">
<json:reader/>
</smooks-resource-list>
Jsonreader可以搜索替换以数字开头的空格,非法字符,键名中的数字,及用新名称替换键名
<?xml version="1.0"?>
<smooks-resource-list xmlns="https://www.smooks.org/xsd/smooks-1.2.xsd" xmlns:yaml="https://www.smooks.org/xsd/smooks/yaml-1.5.xsd">
<yaml:reader keyWhitspaceReplacement="_" keyPrefixOnNumeric="n" illegalElementNameCharReplacement=".">
<yaml:keyMap>
<yaml:key from="some key">someKey</yaml:key>
<yaml:key from="some&key" to="someAndKey" />
</yaml:keyMap>
</yaml:reader>
</smooks-resource-list>
15.Xml到Java
XMLBinding类,专门用于使用<jb:bean> 配置从Java对象模型中读取和写入XML数据,即不需要编写模板将Java对象序列化为基于输出字符的格式。能在单个Java模型中处理XML模型,可将XML消息的多个版本读写到一个Java对象模型中,使用一个版本的XMLBinding实例将XML读入普通Java对象模型,然后用另一个版本的XMLBinding实例编写这些Java对象。
用例四步:
写配置,加载实例,初始化实例,fromXML toXML处理实例。
XMLBinding xmlBinding = new XMLBinding().add("/smooks-configs/order-xml-binding.xml");
xmlBinding.intiailize();
Order order = xmlBinding.fromXML(new StreamSource(inputReader), Order.class);
// Do something with the order....
// Write the Order object model instance back out to XML...
xmlBinding.toXML(order, outputWriter);
使用XMLBinding转换XML消息
XMLBinding xmlBindingV1 = new XMLBinding().add("v1-binding-config.xml");
XMLBinding xmlBindingV2 = new XMLBinding().add("v2-binding-config.xml");
xmlBindingV1.intiailize();
xmlBindingV2.intiailize();
// Read the v1 order XML into the Order Object model...
Order order = xmlBindingV1.fromXML(new StreamSource(inputReader), Order.class);
// Write the Order object model instance back out to XML using the v2 XMLBinding instance...
xmlBindingV2.toXML(order, outputWriter);
绑定配置为源数据模型工作
<jb:bean>,设置CreateOnElement属性 设置为应用于创建bean实例的事件元素。
<jb:value data>属性来选择事件元素/属性,为该bean属性提供绑定数据。
<jb:value decoder>属性。根据实际的属性类型,并不会全部设置。这些必须手动配置,例如,您可能需要配置<jb:decodeParam>一些绑定的解码器子元素。例如用于日期字段。
重复检查绑定配置元素(<jb:value>和<jb:wiring>),确保所有Java属性都包含在生成的配置中。
“$Todo$”令牌--使用空的转换配置,通过报告,看是否被应用
<?xml version="1.0"?>
<smooks-resource-list xmlns="https://www.smooks.org/xsd/smooks-1.2.xsd" xmlns:jb="https://www.smooks.org/xsd/smooks/javabean-1.6.xsd">
<jb:bean beanId="order" class="org.milyn.javabean.Order" createOnElement="$TODO$">
<jb:wiring property="header" beanIdRef="header" />
<jb:wiring property="orderItems" beanIdRef="orderItems" />
<jb:wiring property="orderItemsArray" beanIdRef="orderItemsArray" />
</jb:bean>
<jb:bean beanId="header" class="org.milyn.javabean.Header" createOnElement="$TODO$">
<jb:value property="date" decoder="$TODO$" data="$TODO$" />
<jb:value property="customerNumber" decoder="Long" data="$TODO$" />
<jb:value property="customerName" decoder="String" data="$TODO$" />
<jb:value property="privatePerson" decoder="Boolean" data="$TODO$" />
<jb:wiring property="order" beanIdRef="order" />
</jb:bean>
<jb:bean beanId="orderItems" class="java.util.ArrayList" createOnElement="$TODO$">
<jb:wiring beanIdRef="orderItems_entry" />
</jb:bean>
<jb:bean beanId="orderItems_entry" class="org.milyn.javabean.OrderItem" createOnElement="$TODO$">
<jb:value property="productId" decoder="Long" data="$TODO$" />
<jb:value property="quantity" decoder="Integer" data="$TODO$" />
<jb:value property="price" decoder="Double" data="$TODO$" />
<jb:wiring property="order" beanIdRef="order" />
</jb:bean>
<jb:bean beanId="orderItemsArray" class="org.milyn.javabean.OrderItem[]" createOnElement="$TODO$">
<jb:wiring beanIdRef="orderItemsArray_entry" />
</jb:bean>
<jb:bean beanId="orderItemsArray_entry" class="org.milyn.javabean.OrderItem" createOnElement="$TODO$">
<jb:value property="productId" decoder="Long" data="$TODO$" />
<jb:value property="quantity" decoder="Integer" data="$TODO$" />
<jb:value property="price" decoder="Double" data="$TODO$" />
<jb:wiring property="order" beanIdRef="order" />
</jb:bean>
</smooks-resource-list>
JavaResult--JavaResult包含了bean上下文最终内容,可在配置文件中设置返回的Bean集
<?xml version="1.0"?>
<smooks-resource-list xmlns="https://www.smooks.org/xsd/smooks-1.2.xsd"
xmlns:jb="https://www.smooks.org/xsd/smooks/javabean-1.6.xsd">
<!-- Capture some data from the message into the bean context... -->
<jb:bean beanId="order" class="com.acme.Order" createOnElement="order">
<jb:value property="orderId" data="order/@id"/>
<jb:value property="customerNumber" data="header/customer/@number"/>
<jb:value property="customerName" data="header/customer"/>
<jb:wiring property="orderItems" beanIdRef="orderItems"/>
</jb:bean>
<jb:bean beanId="orderItems" class="java.util.ArrayList" createOnElement="order">
<jb:wiring beanIdRef="orderItem"/>
</jb:bean>
<jb:bean beanId="orderItem" class="com.acme.OrderItem" createOnElement="order-item">
<jb:value property="itemId" data="order-item/@id"/>
<jb:value property="productId" data="order-item/product"/>
<jb:value property="quantity" data="order-item/quantity"/>
<jb:value property="price" data="order-item/price"/>
</jb:bean>
<!-- Only retain the "order" bean in the root of any final JavaResult. -->
<jb:result retainBeans="order"/>
</smooks-resource-list>
对数据进行操作
重命名或移除元素,更改属性值
<core:setElementData>*在目标元素上设置数据(名称和/或attribites)。
<core:remove>*删除一个元素(如果定义了,不要将其序列化到StreamResult)。
<core:removeAttribute>*删除属性(如果定义了,不要将其序列化到StreamResult)。
<?xml version="1.0"?>
<smooks-resource-list xmlns="https://www.smooks.org/xsd/smooks-1.2.xsd"
xmlns:core="https://www.smooks.org/xsd/smooks/smooks-core-1.5.xsd">
<!-- Other configs, e.g. bean bindings etc -->
<!-- Remove an element... -->
<core:remove element="order/header" />
<!-- Remove an attribute... -->
<core:removeAttribute onElement="order" name="orderStatus" />
<!-- Rename an element... -->
<core:setElementData onElement="order/order-items" name="items" />
<!-- Rename an element and set/change some of its attribute... -->
<core:setElementData onElement="order/order-item" name="item">
<!-- Note you can use templating to inject data from the Bean Context into attribute values... -->
<core:attribute name="status" value="${items.item.state}" />
</core:setElementData>
</smooks-resource-list>
对输出结果进行操作
1.要声明Smooks生成的结果类型,可以使用“exports”元素
<smooks-resource-list xmlns="https://www.smooks.org/xsd/smooks-1.2.xsd" xmlns:core="https://www.smooks.org/xsd/smooks/smooks-core-1.5.xsd">
<core:exports>
<core:result type="org.milyn.payload.JavaResult"/>
</core:exports>
</smooks-resource-list>
Java----------->
Exports exports = Exports.getExports(smooks.getApplicationContext());
if (exports.hasExports())
{
// Create the instances of the Result types.
// (Only the types, i.e the Class type are declared in the 'type' attribute.
Result[] results = exports.createResults();
smooks.filterSource(executionContext, getSource(exchange), results);
// The Results(s) will now be populate by Smooks filtering process and
// available to the framework in question.
}
2.若是只对于结果的部分感兴趣的话,可以只返回结果的一部分
<smooks-resource-list xmlns="https://www.smooks.org/xsd/smooks-1.2.xsd" xmlns:core="https://www.smooks.org/xsd/smooks/smooks-core-1.5.xsd">
<core:exports>
<core:result type="org.milyn.payload.JavaResult" extract="orderBean"/>
</core:exports>
</smooks-resource-list>
Exports exports = Exports.getExports(smooks.getApplicationContext());
if (exports.hasExports())
{
// Create the instances of the Result types.
// (Only the types, i.e the Class type are declared in the 'type' attribute.
Result[] results = exports.createResults();
smooks.filterSource(executionContext, getSource(exchange), results);
List<object> objects = Exports.extractResults(results, exports);
// Now make the object available to the framework that this code is running:
// Camel, JBossESB, Mule etc.
}