3

我有一个源 xml,如下所示:

<SampleRequest xmlns="http://sample.com/s"
       xmlns:s1="http://sample.com/s1"
       xmlns:s2="http://sample.com/s2"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://sample.com/s schema.xsd">
<data>
<s1:customer s1:firstName="Jim" s1:lastName="Ellison"/>
<s2:address>
    123 test street
</s2:address>
</data>
</SampleRequest>

我需要将其转换为以下

<SampleRequest xmlns="http://sample.com/t"
       xmlns:t1="http://sample.com/t1"
       xmlns:t2="http://sample.com/t2"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://sample.com/t targetSchema.xsd">
<data>
<t1:customer t1:firstName="Jim" t1:lastName="Ellison"/>
<t2:address>
    123 test street
</t2:address>
</data>
</SampleRequest>

两个 xmls 具有相同的架构但不同的命名空间。

我试图使用以下 xslt

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
            xmlns="http://sample.com/s"
            xmlns:s1="http://sample.com/s1"
            xmlns:s2="http://sample.com/s2"
            xmlns:t1="http://sample.com/t1"
            xmlns:t2="http://sample.com/t2"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="s1 s2">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
    <SampleRequest xmlns="http://sample.com/t"
       xmlns:t1="http://sample.com/t1"
       xmlns:t2="http://sample.com/t2"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <xsl:attribute name="xsi:schemaLocation" namespace="http://www.w3.org/2001/XMLSchema-instance">
            http://sample.com/t targetSchema.xsd
        </xsl:attribute>
        <xsl:copy>
             <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </SampleRequest>
</xsl:template>
<xsl:template match="s1:*"> 
    <xsl:element name="t1:{local-name()}" namespace="http://sample.com/t1">      
        <xsl:apply-templates select="* | node()"/>
    </xsl:element>
</xsl:template>

<xsl:template match="s2:*"> 
    <xsl:element name="t2:{local-name()}" namespace="http://sample.com/t2">
        <xsl:apply-templates select="* | node()"/>
    </xsl:element>
</xsl:template>
</xsl:stylesheet>

我得到以下结果

<?xml version="1.0" encoding="UTF-8"?><SampleRequest xmlns="http://sample.com/t"   xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:t2="http://sample.com/t2" xmlns:t1="http://sample.com/t1" xsi:schemaLocation=" http://sample.com/t targetSchema.xsd">
<t1:customer/>
<t2:address>
    123 test street
</t2:address>
</SampleRequest>

似乎所有属性都丢失了。我对 XSLT 很陌生,感谢每一点帮助

4

1 回答 1

8

您的 XSLT 中有两个问题。首先,在匹配 s1 和 s2 元素的地方,您随后不会尝试将模板应用于任何属性。您需要替换此语句

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

有了这个声明

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

其次,您没有任何模板来匹配这些属性。你需要一个这样的模板:

<xsl:template match="@s1:*">
    <xsl:attribute name="t1:{local-name()}">
        <xsl:value-of select="." />
    </xsl:attribute>
</xsl:template>

试试这个 XSLT

<xsl:stylesheet version="1.0" 
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
   xmlns="http://sample.com/s" 
   xmlns:s1="http://sample.com/s1" 
   xmlns:s2="http://sample.com/s2" 
   xmlns:t1="http://sample.com/t1" 
   xmlns:t2="http://sample.com/t2" 
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
   xmlns:xs="http://www.w3.org/2001/XMLSchema" 
   exclude-result-prefixes="s1 s2">

   <xsl:output method="xml" encoding="UTF-8" indent="yes"/>

   <xsl:strip-space elements="*"/>

   <xsl:template match="/">
      <SampleRequest 
        xmlns="http://sample.com/t" 
        xmlns:t1="http://sample.com/t1" 
        xmlns:t2="http://sample.com/t2" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
         <xsl:attribute name="xsi:schemaLocation">http://sample.com/t targetSchema.xsd</xsl:attribute>
         <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
         </xsl:copy>
      </SampleRequest>
   </xsl:template>

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

   <xsl:template match="@s1:*">
      <xsl:attribute name="t1:{local-name()}">
         <xsl:value-of select="."/>
      </xsl:attribute>
   </xsl:template>

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

   <xsl:template match="@s2:*">
      <xsl:attribute name="t2:{local-name()}">
         <xsl:value-of select="."/>
      </xsl:attribute>
   </xsl:template>
</xsl:stylesheet>

当应用于您的示例 XML 时,将输出以下内容:

<SampleRequest 
   xsi:schemaLocation="http://sample.com/t targetSchema.xsd" 
   xmlns:t1="http://sample.com/t1" 
   xmlns:t2="http://sample.com/t2" 
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
   xmlns:xs="http://www.w3.org/2001/XMLSchema" 
   xmlns="http://sample.com/t">
   <t1:customer t1:firstName="Jim" t1:lastName="Ellison"/>
   <t2:address> 123 test street </t2:address>
</SampleRequest>
于 2012-04-12T14:26:36.527 回答