我有一条消息
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns="http://xmlns.oracle.com/policyautomation/hub/12.0/metadata/types">
<soapenv:Header/>
<soapenv:Body>
<load-request root="Vehicles" region="en-US" language="en-US" timezone="Etc/GMT">
<tables>
<table name="Vehicles">
<link name="Cars" target="Car" />
</table>
</tables>
</load-request>
</soapenv:Body>
我需要对它进行两次转换:
我知道如何变换load-request,并尝试this solution删除SOAP,但无法将两者合并并删除信封并转换正文(加载请求 )单个xslt。 结果XML应该是:
<load-request>
<root>Vehicles</root>
<region>en-US</region>
<language>en-US</language>
<timezone>Etc/GMT</timezone>
<request-context>
<parameter>
<name>MyParam1</name>
<value>MyValue</value>
</parameter>
</request-context>
<tables>
<table>
<name>Vehicles</name>
<link>
<name>Cars</name>
<target>Car</target>
</link>
</table>
</tables>
</load-request>
我使用的XSLT:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" >
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="soapenv:*">
<xsl:apply-templates select="@* | node()" />
</xsl:template>
<xsl:template match="load-request">
<xsl:element name="load-request">
<xsl:element name="root">
<xsl:value-of select="@root"/>
</xsl:element>
<xsl:element name="region">
<xsl:value-of select="@region"/>
</xsl:element>
<xsl:element name="language">
<xsl:value-of select="@language"/>
</xsl:element>
<xsl:element name="timezone">
<xsl:value-of select="@timezone"/>
</xsl:element>
<xsl:apply-templates select="request-context"/>
<xsl:apply-templates select="tables"/>
</xsl:element>
</xsl:template>
<xsl:template match="request-context">
<xsl:element name="request-context">
<xsl:for-each select="parameter">
<xsl:element name="parameter">
<xsl:element name="name">
<xsl:value-of select="@name"/>
</xsl:element>
<xsl:element name="value">
<xsl:value-of select="@value"/>
</xsl:element>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:template>
<xsl:template match="tables">
<xsl:element name="tables">
<xsl:for-each select="table">
<xsl:element name="table">
<xsl:element name="name">
<xsl:value-of select="@name"/>
</xsl:element>
<xsl:apply-templates select="link"/>
<xsl:for-each select="field">
<xsl:element name="field">
<xsl:element name="name">
<xsl:value-of select="@name"/>
</xsl:element>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:template>
<xsl:template match="link">
<xsl:element name="link">
<xsl:element name="name">
<xsl:value-of select="@name"/>
</xsl:element>
<xsl:element name="target">
<xsl:value-of select="@target"/>
</xsl:element>
</xsl:element>
</xsl:template>
<xsl:template match="field">
<xsl:for-each select="field">
<xsl:element name="field">
<xsl:element name="name">
<xsl:value-of select="@name"/>
</xsl:element>
</xsl:element>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
更新: 答案适用于输入。你能否请进一步调整: 在我的一些场景中,将属性转换为元素是不够的。
下面的消息<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns="http://xmlns.oracle.com/policyautomation/hub/12.0/metadata/types">
<soapenv:Header/>
<soapenv:Body>
<load-request root="Complains">
<field name="Explanation">
<text-val name="Text">The client needs a new toothbrush</text-val>
</field>
</load-request>
</soapenv:Body>
需要成为
<load-request>
<root>Complains</root>
<field>
<name>Explanation</name>
<text-val>
<name>Text</name>
<value>The client needs a new toothbrush</value>
</text-val>
</field>
</load-request>
答案 0 :(得分:4)
从更简单的事情开始怎么样:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
exclude-result-prefixes="soapenv">
<xsl:strip-space elements="*"/>
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<!-- remove all elements in the soapenv namespace -->
<xsl:template match="soapenv:*">
<xsl:apply-templates select="node()"/>
</xsl:template>
<!-- for the remaining elements (i.e. elements in the default namespace) ... -->
<xsl:template match="*">
<!-- ... create a new element with similar name in no-namespace -->
<xsl:element name="{local-name()}">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
<!-- convert attributes to elements -->
<xsl:template match="@*">
<xsl:element name="{local-name()}">
<xsl:value-of select="." />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
应用于您的示例输入,已针对格式良好(!)进行修复:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://xmlns.oracle.com/policyautomation/hub/12.0/metadata/types">
<soapenv:Header/>
<soapenv:Body>
<load-request root="Vehicles" region="en-US" language="en-US" timezone="Etc/GMT">
<tables>
<table name="Vehicles">
<link name="Cars" target="Car"/>
</table>
</tables>
</load-request>
</soapenv:Body>
</soapenv:Envelope>
生成以下结果:
<?xml version="1.0" encoding="UTF-8"?>
<load-request>
<root>Vehicles</root>
<region>en-US</region>
<language>en-US</language>
<timezone>Etc/GMT</timezone>
<tables>
<table>
<name>Vehicles</name>
<link>
<name>Cars</name>
<target>Car</target>
</link>
</table>
</tables>
</load-request>
响应您的修改:
如果具有文本值的任何元素都可以转换,以便文本值变为名为value
的子元素,则只需在样式表中添加另一个通用模板:
<xsl:template match="text()">
<value>
<xsl:value-of select="." />
</value>
</xsl:template>
如果上述情况不正确,并且您需要显式地处理源XML中的特定元素,那么您需要在样式表中声明源的默认命名空间,为其分配前缀并在寻址元素时使用该前缀。在这种情况下,stylesheet
元素将如下所示:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:tps="http://xmlns.oracle.com/policyautomation/hub/12.0/metadata/types"
exclude-result-prefixes="soapenv tps">
,您的模板将采用以下形式:
<xsl:template match="tps:text-val">
<text-val>
<!-- more instructions here -->
</text-val>
</xsl:template>