XSLT删除肥皂环境&将SINGLE XSI Tag复制到自己的字段中

时间:2012-11-02 11:03:34

标签: xml xslt

我正在尝试从soap env中复制XML,并且我已经能够成功完成此操作。接下来我想要删除所有XMLNS,这也是我能够成功完成的。但是,我现在尝试从XML有效负载的中间选择一个XSI属性,并在XML中创建一个包含teh XSI = TYPE字段内容的新字段。我将展示我想要做的事情:

示例XML:

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soapenv:Body>
        <notifications xmlns="http://soap.sforce.com/2005/09/outbound">
            <ActionId>04kf000000000FfAAI</ActionId>
            <SessionId xsi:nil="true"/>
            <Notification>
                <Id>04lf00000000xvQAAQ</Id>
                <sObject xsi:type="sf:Account" xmlns:sf="urn:sobject">
                    <sf:Id>001f0000006UzdCAAS</sf:Id>
                    <sf:Customer_Number__c>dummy1234</sf:Customer_Number__c>
                    <sf:FirstName>Test</sf:FirstName>
                    <sf:LastModifiedDate>2012-10-15T10:59:54.000Z</sf:LastModifiedDate>
                    <sf:LastName>Test</sf:LastName>
                </sObject>
            </Notification>
        </notifications>
    </soapenv:Body>
</soapenv:Envelope>

CURRENT XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:r="http://soap.sforce.com/2005/09/outbound"
    exclude-result-prefixes="r">

    <xsl:output method="xml" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="/">
        <xsl:apply-templates select="/soap:Envelope//r:notifications"/>
    </xsl:template>

    <xsl:template match ="*" >
        <xsl:element name ="{local-name()}" >
            <xsl:apply-templates select ="@* | node()" />
        </xsl:element>
    </xsl:template>

</xsl:stylesheet>

输出:

<?xml version="1.0" encoding="utf-8"?>
<notifications>
   <ActionId>04kf000000000FfAAI</ActionId>
   <SessionId>true</SessionId>
   <Notification>
      <Id>04lf00000000xvQAAQ</Id>
      <sObject>tableName<Id>001f0000006UzdCAAS</Id>
         <Customer_Number__c>dummy1234</Customer_Number__c>
         <FirstName>Test</FirstName>
         <LastModifiedDate>2012-10-15T10:59:54.000Z</LastModifiedDate>
         <LastName>Test</LastName>
      </sObject>
   </Notification>
</notifications>

这是不正确的,因为只是在sObject中放入XSI:TYPE的内容,我需要在它自己的字段中,例如这是所需的输出:

<?xml version="1.0" encoding="utf-8"?>
<notifications>
   <ActionId>04kf000000000FfAAI</ActionId>
   <SessionId>true</SessionId>
   <Notification>
      <Id>04lf00000000xvQAAQ</Id>
      <sObject>
         <tableName>tableName</tableName>
         <Id>001f0000006UzdCAAS</Id>
         <Customer_Number__c>dummy1234</Customer_Number__c>
         <FirstName>Test</FirstName>
         <LastModifiedDate>2012-10-15T10:59:54.000Z</LastModifiedDate>
         <LastName>Test</LastName>
      </sObject>
   </Notification>
</notifications>

1 个答案:

答案 0 :(得分:2)

通过添加新模板来对sObject进行自定义处理,您可以将属性处理为新元素,然后继续处理。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:r="http://soap.sforce.com/2005/09/outbound"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    exclude-result-prefixes="r soap xsi">

    <xsl:output method="xml" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="/">
        <xsl:apply-templates select="/soap:Envelope//r:notifications"/>
    </xsl:template>

    <xsl:template match ="*" >
        <xsl:element name ="{local-name()}" >
            <xsl:apply-templates select ="@* | node()" />
        </xsl:element>
    </xsl:template>

    <xsl:template match="*[local-name()='sObject']">
        <sObject>
            <tableName>
                <xsl:value-of select="@xsi:type"/>
            </tableName>
            <xsl:apply-templates />
        </sObject>
    </xsl:template>

</xsl:stylesheet>

这会产生输出:

<?xml version="1.0" encoding="utf-8"?>
<notifications>
  <ActionId>04kf000000000FfAAI</ActionId>
  <SessionId>true</SessionId>
  <Notification>
    <Id>04lf00000000xvQAAQ</Id>
    <sObject>
      <tableName>sf:Account</tableName>
      <Id>001f0000006UzdCAAS</Id>
      <Customer_Number__c>dummy1234</Customer_Number__c>
      <FirstName>Test</FirstName>
      <LastModifiedDate>2012-10-15T10:59:54.000Z</LastModifiedDate>
      <LastName>Test</LastName>
    </sObject>
  </Notification>
</notifications>

为了保持原始xslt的精神,如果你想避免添加xsi命名空间,你也可以像这样复制属性:

<xsl:value-of select="@*[local-name()='type']"/>