2013-04-07 104 views
1

我试图构建一个Soap请求。所需的输出是:如何从xslt输出xml中删除不需要的空xmlns

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" 
xmlns:soap1="http://acme.com/ws/soapheaders"> 
<soap:Header> 
    <soap1:locale>en</soap1:locale> 
    <soap1:authentication> 
     <soap1:username>john.doe</soap1:username> 
     <soap1:password>psw</soap1:password> 
    </soap1:authentication> 
</soap:Header> 

这里是我的测试XSL(lanuage,用户名和密码在实际应用中传递):

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/> 
<xsl:param name="language" select="'en'"/> 
<xsl:param name="username" select="'john.doe'"/> 
<xsl:param name="password" select="'psw'"/> 
<xsl:template match="/"> 
    <soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" 
     xmlns:soap1="http://acme.com/ws/soapheaders" > 
     <xsl:call-template name="soapHeader"/>    
     <xsl:call-template name="soapBody"/> 
    </soap:Envelope> 
</xsl:template> 
<xsl:template name="soapHeader"> 
    <soap:Header> 
     <soap1:locale><xsl:value-of select="$language" /></soap1:locale> 
     <soap1:authentication> 
      <soap1:username><xsl:value-of select="$username" /></soap1:username> 
      <soap1:password><xsl:value-of select="$password" /></soap1:password> 
     </soap1:authentication> 
    </soap:Header> 
</xsl:template> 
<xsl:template name="soapBody"> 
</xsl:template> 
</xsl:stylesheet> 

但是,输出是:

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:soap1="http://acme.com/ws/soapheaders"> 
<soap:Header xmlns:soap=""> 
    <soap1:locale xmlns:soap1="">en</soap1:locale> 
    <soap1:authentication xmlns:soap1=""> 
     <soap1:username>john.doe</soap1:username> 
     <soap1:password>psw</soap1:password> 
    </soap1:authentication> 
</soap:Header> 

存在不需要的空名称空间,如xmlns:soap =“”,xmlns:soap1 =“”。你能指点我正确的方向来消除这些不需要的文物吗?

谢谢。

+0

User2254613,我强烈建议使用一种设计模式,使演示文稿与逻辑完全分离 - 又名“填充空白”技术。 – 2013-04-07 16:09:58

回答

0

我很惊讶你的XSLT处理器接受XSLT,因为它不是有效的XML,而是使之有效的,并且也(我相信)解决您的问题,您应该<xsl:stylesheet>元素,而不是对上申报命名空间<soap:Envelope>元件:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" 
       xmlns:soap="http://www.w3.org/2003/05/soap-envelope" 
       xmlns:soap1="http://acme.com/ws/soapheaders"> 
+0

JLRishe,谢谢你的帮助。我用Altova XMLSpy测试了它,它并没有抱怨xslt。将所有的namsespaces移动到你所建议的位置就行了!谢谢。 – user2254613 2013-04-07 15:23:15

-1

我强烈建议到呈现从逻辑分离。事实上,您可以进行独立于任何可能演示文稿的转换。

这里谈到的 “填充最坯” 技术(注意,这也解决了您不需要的命名空间的问题):

源XML文档

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" 
xmlns:soap1="http://acme.com/ws/soapheaders" xmlns:gen="my:gen"> 
    <soap:Header> 
     <soap1:locale><gen:language/></soap1:locale> 
     <soap1:authentication> 
      <soap1:username><gen:username/></soap1:username> 
      <soap1:password><gen:password/></soap1:password> 
     </soap1:authentication> 
    </soap:Header> 
</soap:Envelope> 

Presentation-独立转化

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:gen="my:gen"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 
    <xsl:param name="language" select="'en'"/> 
    <xsl:param name="username" select="'john.doe'"/> 
    <xsl:param name="password" select="'psw'"/> 

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

<xsl:template match="gen:*"> 
    <xsl:value-of select= 
    "document('')/*/xsl:param[@name=local-name(current())]/@select"/> 
</xsl:template> 
</xsl:stylesheet> 

结果

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:soap1="http://acme.com/ws/soapheaders" xmlns:gen="my:gen"> 
    <soap:Header> 
     <soap1:locale>'en'</soap1:locale> 
     <soap1:authentication> 
     <soap1:username>'john.doe'</soap1:username> 
     <soap1:password>'psw'</soap1:password> 
     </soap1:authentication> 
    </soap:Header> 
</soap:Envelope> 

您可以现在有许多不同的呈现布局的需要,并没有任何变化相同的转换(提供所有必需的参数已指定)产生任何格式

例如,如果你想生产这种新格式的结果:

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:soap1="http://acme.com/ws/soapheaders"> 
    <soap:Header> 
     <soap1:personalized> 
     <soap1:locale> 
      <soap1:language>'en'</soap1:language> 
     </soap1:locale> 
     <soap1:authentication> 
      <soap1:username>'john.doe'</soap1:username> 
      <soap1:password>'psw'</soap1:password> 
     </soap1:authentication> 
     </soap1:personalized> 
    </soap:Header> 
</soap:Envelope> 

只适用于下面的XML文档相同的转换:

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" 
xmlns:soap1="http://acme.com/ws/soapheaders" xmlns:gen="my:gen"> 
    <soap:Header> 
     <soap1:personalized> 
     <soap1:locale> 
      <soap1:language><gen:language/></soap1:language> 
    </soap1:locale> 
     <soap1:authentication> 
      <soap1:username><gen:username/></soap1:username> 
      <soap1:password><gen:password/></soap1:password> 
     </soap1:authentication> 
     </soap1:personalized> 
    </soap:Header> 
</soap:Envelope> 

进一步泛化可以通过提供布局文档的URL和参数文档的url作为变换的参数来实现。

+0

我不是那种低估了这一点的人,但是你的输出在值的周围有撇号,如果参数值是从外部传入的(提问者说他​​最终会这样做),这将不起作用。 – JLRishe 2013-04-07 19:11:33

+0

@JLRishe,当我指出我的答案结束时,这只是一个演示。这种技术的完整和普遍应用将接受布局和参数作为外部XML文档URI。 – 2013-04-07 19:27:55

相关问题