XSLT更改名称空间前缀以及属性转换

时间:2015-08-25 11:28:40

标签: xml xslt

我正在尝试将元素转换为属性以及添加名称空间前缀。但是我不能在同一个XSLT中做这两件事。

源XML:

    <createDocument> 
    <ecm_cmd_doc> 
        <ecm_application_name>preview</ecm_application_name>  
        <ecm_operation> 
            <mode>asynchronous</mode>  
            <name>create</name> 
        </ecm_operation>  
        <doc_in_create> 
            <doc_object_attribute_create> 
                <doc_format>pdf</doc_format>  
                <dctm_folder/>  
                <dctm_object_type>ecm_gbd_check_image_doc</dctm_object_type>  
                <doc_attr> 
                    <attr_name>document_code</attr_name>  
                    <attr_value>9002</attr_value> 
                </doc_attr>                     
                <doc_attr> 
                    <attr_name>bill_customer_identifier</attr_name>  
                    <attr_value>234567898</attr_value> 
                </doc_attr> 
                <file_info> 
                    <URL>1234567890.pdf</URL>  
                    <URI>1234567890.pdf</URI>  
                    <file_in_target>false</file_in_target> 
                </file_info> 
            </doc_object_attribute_create> 
        </doc_in_create> 
    </ecm_cmd_doc> 
</createDocument>    

使用的XSLT:

      <xsl:stylesheet env:encodingStyle="" xmlns:p="http://tempuri.org/"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" version="1.0">
      <xsl:output method="xml" indent="yes" omit-xml-declaration="yes" /> 
      <xsl:strip-space elements="*"/> 

      <xsl:template match="/">
      <xsl:apply-templates select="/*"/>  
      </xsl:template>

      <xsl:template match="*">
      <xsl:copy> 
      <xsl:for-each select="mode|doc_format|URL|URI|file_in_target|xmlns|dctm_folder|name|dctm_object_type|attr_value|attr_name">
       <xsl:attribute name="{name()}">
       <xsl:value-of select="."/> 
       </xsl:attribute>
       </xsl:for-each>
       <xsl:apply-templates select="node()[not(self::mode or self::dctm_folder or self::doc_format or self::xmlns or self::URL or self::URI or self::file_in_target or self::name or self::dctm_object_type or self::attr_value or self::attr_name)]" /> 
       </xsl:copy>
       </xsl:template>

       </xsl:stylesheet>

预期产出:

    <p:createDocument xmlns:p="http://ecm.com/ecm_c_dc">
    <p:ecm_cmd_doc>
    <p:ecm_application_name>preview</p:ecm_application_name>
    <p:ecm_operation mode="asynchronous" name="create"/>
    <p:doc_in_create>
     <p:doc_object_attribute_create doc_format="pdf"
                                  dctm_folder=""
                                  dctm_object_type="ecm_gbd_check_image_doc">
        <p:doc_attr attr_name="document_code" attr_value="9002"/>
        <p:doc_attr attr_name="bill_customer_identifier" attr_value="234567898"/>
        <p:file_info URL="1234567890.pdf" URI="1234567890.pdf" file_in_target="false"/>
     </p:doc_object_attribute_create>
     </p:doc_in_create>
     </p:ecm_cmd_doc>
     </p:createDocument>

非常感谢您的帮助!

1 个答案:

答案 0 :(得分:3)

如果要在不同的命名空间中输出元素,则无法使用xsl:copy

请尝试这种方式:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:p="http://ecm.com/ecm_c_dc">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="*">
    <xsl:element name="p:{name()}">
        <xsl:apply-templates/>
    </xsl:element>
</xsl:template>

<xsl:template match="mode|doc_format|URL|URI|file_in_target|xmlns|dctm_folder|name|dctm_object_type|attr_value|attr_name">
    <xsl:attribute name="{name()}">
        <xsl:value-of select="."/> 
    </xsl:attribute>
</xsl:template>

</xsl:stylesheet>