2011-03-08 97 views
1

这些是SVG元素,并且SVG文档的提供者添加了所有类型的扩展,我们不能使用和不需要。所以我想删除这些扩展属性。XSLT复制元素属性,除非属性位于给定名称空间中

我基本上使用身份变换。我想这个元素:

<text id="1" 
     i:knockout="Off" 
     i:objectType="pointText" 
     style="font-size:16;" 
    >Hi</text> 

复制为

<text id="1" style="font-size:16;">Hi</text> 

任何帮助表示赞赏。

编辑

不幸的是,我在上面选择的例子是不是一个真正的一个。这一个是:

<?xml version="1.0" encoding="UTF-8"?> 
<svg xmlns="http://www.w3.org/2000/svg" 
    xmlns:i="http://ns.adobe.com/AdobeIllustrator/10.0/" 
    i:viewOrigin="-39.4106 906.6265" i:rulerOrigin="0 0" i:pageBounds="0 840 592 0" > 
    <g i:extraneous="self"> 
    </g> 
</svg> 

和我要的是:

<?xml version="1.0" encoding="UTF-8"?> 
<svg xmlns="http://www.w3.org/2000/svg" 
    > 
    <g> 
    </g> 
</svg> 
+1

如果你使用的是身份转换,你只需要为像'@i:*'这样的模式添加一个空的规则(当然你需要一个适当的命名空间声明) – 2011-03-08 20:53:04

+0

好问题,+ 1。查看我的答案,获得完整,简短和简单的解决方案。 :) – 2011-03-08 21:04:19

+0

@Alejandro:是的,但这不会从元素中删除不需要的名称空间节点。我的解决方案删除这个不需要的名称空间节点 – 2011-03-08 21:05:15

回答

0

这种转变

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:template match="*"> 
    <xsl:element name="{name()}" namespace="{namespace-uri()}"> 
    <xsl:copy-of select= 
    "namespace::*[not(.='i:i')]"/> 
    <xsl:apply-templates select="node()|@*"/> 
    </xsl:element> 
</xsl:template> 

<xsl:template match="@*[namespace-uri()='i:i']"/> 

<xsl:template match="@*"> 
    <xsl:copy-of select="."/> 
</xsl:template> 
</xsl:stylesheet> 

时所提供的XML文档应用:

<text id="1" xmlns:i="i:i" 
    i:knockout="Off" 
    i:objectType="pointText" 
    style="font-size:16;">Hi</text> 

产生想要的,正确的结果:

<text id="1" style="font-size:16;">Hi</text> 

UPDATE:该OP现在已经指定他已经绑定到前缀"i"确切的命名空间。

在这种情况下,一个简单的"i:i"http://ns.adobe.com/AdobeIllustrator/10.0/替换为我们提供了新的解决方案:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:param name="pUnwantedNS" select="'http://ns.adobe.com/AdobeIllustrator/10.0/'"/> 

    <xsl:template match="*"> 
     <xsl:element name="{name()}" namespace="{namespace-uri()}"> 
      <xsl:copy-of select="namespace::*[not(.=$pUnwantedNS)]"/> 
      <xsl:apply-templates select="node()|@*"/> 
     </xsl:element> 
    </xsl:template> 

    <xsl:template match="@*"> 
     <xsl:copy-of select="."/> 
    </xsl:template> 

    <xsl:template match= 
    "@*[namespace-uri()='http://ns.adobe.com/AdobeIllustrator/10.0/']"/> 
</xsl:stylesheet> 

当上新提供的XML文档应用:

<svg xmlns="http://www.w3.org/2000/svg" 
    xmlns:i="http://ns.adobe.com/AdobeIllustrator/10.0/" 
    i:viewOrigin="-39.4106 906.6265" 
    i:rulerOrigin="0 0" 
    i:pageBounds="0 840 592 0" > 
    <g i:extraneous="self"></g> 
</svg> 

通缉,再次产生正确结果

<svg xmlns="http://www.w3.org/2000/svg"> 
    <g /> 
</svg> 
+0

'namespace :: * [not(namespace-uri()='i:i')]'看起来很奇怪 - 名称空间节点的名称是ns前缀,它没有URI部分。在2.0中,空规则当然可以用'match =“i:*”'模式来编写。 – 2011-03-09 00:06:25

+0

@ Michael-Kay:谢谢你注意到这一点。立即修复。 – 2011-03-09 00:48:44

+0

这对我给出的过于简化的例子有用。我更新了一个更现实的。 – 2011-03-09 15:43:55