简体   繁体   中英

Add nodes from xml properties to soap message with xsl

Please I need your help,

XML: I Have this SOAP Message:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
 <Service>
  <ServiceRequest>
   <tag3>value3</tag3>
  </ServiceRequest>
 </Service>
</soapenv:Body>
</soapenv:Envelope>

XSL: I need to add nodes from xml properties. I try with this xsl:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml">
<xsl:output encoding="UTF-8" indent="yes" method="xml" standalone="no" omit-xml-declaration="no"/>
<xsl:variable name="props">
<properties>
 <property>
  <key>tag1</key>
  <value>value1</value>
 </property>
 <property>
  <key>tag2</key>
  <value>value2</value>
 </property>
</properties>
</xsl:variable>

<xsl:template match="@* | node()">
<xsl:copy>
 <xsl:apply-templates select="@* | node()" />
</xsl:copy>
</xsl:template>

<xsl:template match="ServiceRequest">
<xsl:copy>
 <xsl:apply-templates select="@* | node()" />
  <xsl:for-each select="$props/properties/property">
   <xsl:variable name="tag" select="key" />
   <xsl:element name="{$tag}">
    <xsl:value-of select="value" />
   </xsl:element>
  </xsl:for-each>
 </xsl:copy>
</xsl:template>
</xsl:stylesheet>

XML after XSL: I need a result like this:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
 <Service>
  <ServiceRequest>
   <tag1>value1</tag1>
   <tag2>value2</tag2>
   <tag3>value3</tag3>
  </ServiceRequest>
 </Service>
</soapenv:Body>
</soapenv:Envelope>

But the XSL does'n work. Can you help me please?

The problem is that the XSLT has a default namespace xmlns="http://www.w3.org/1999/xhtml , so the properties and property element are in that namespace, and so select="$props/properties/property" does not match anything because they are looking for elements in the null namespace.

The default namespace seems not to be necessary, so the easiest fix is just to drop it.

Another possible problem is that the $prop variable contains a XML fragment and not a node-set - this means that it needs to be converted to a node set before being used in the for-each - this is done with XSLT extension functions that are implementation dependent.

Using the Microsoft XSLT processor the correct XSLT looks like this:

 <xsl:stylesheet 
  version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
  xmlns:msxsl="urn:schemas-microsoft-com:xslt" 
  exclude-result-prefixes="msxsl">

  <xsl:output encoding="UTF-8" indent="yes" method="xml" standalone="no" omit-xml-declaration="no"/>
  <xsl:variable name="props">
    <properties>
      <property>
        <key>tag1</key>
        <value>value1</value>
      </property>
      <property>
        <key>tag2</key>
        <value>value2</value>
      </property>
    </properties>
  </xsl:variable>

  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()" />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="ServiceRequest">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()" />
      <xsl:for-each select="msxsl:node-set($props)/properties/property">
        <xsl:variable name="tag" select="key" />
        <xsl:element name="{$tag}">
          <xsl:value-of select="value" />
        </xsl:element>
      </xsl:for-each>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM