2015-02-06 98 views
0

在下面的XML中,需要使用XPath替换名称空间。如何使用xpath替换xml中的第一个节点属性值

<application xmlns="http://ns.adobe.com/air/application/4.0"> 
    <child id="1"></child> 
    <child id="2"></child> 
</application> 

我试着用

/application/@xmlns 

/*[local-name()='application']/@[local-name()='xmlns'] 

双方未能给予的愿望输出。为了替换文本,我使用了xmltask替换。

<xmltask source="${temp.file1}" dest="${temp.file1}"> 
    <replace path="/application/@xmlns" withText="http://ns.adobe.com/air/application/16.0" /> 
</xmltask> 
+0

您可以发布您的代码,您已经使用了更换? – ArinCool 2015-02-06 07:08:12

回答

5

问题是xmlns不是属性。您无法使用XPath进行选择。

命名空间是节点名称的一部分在XML:<foo xmlns="urn:foo-namespace" /><foo xmlns="urn:bar-namespace" />两次与相同的名称和不同的属性节点,它们是具有不同名称的两个节点和没有属性。

如果要更改命名空间,则必须构造一个全新的节点。

XSLT是更好的适合于这项任务:

<!-- update-air-ns.xsl --> 
<xsl:transform 
    version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:air4="http://ns.adobe.com/air/application/4.0" 
    xmlns="http://ns.adobe.com/air/application/16.0" 
> 
    <xsl:output method="xml" encoding="UTF-8" indent="yes" /> 

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

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

这XSLT转换做了两两件事:

  • 第一模板(身份模板)递归复制节点,除非有更好的匹配给定节点的模板
  • 第二个模板匹配air4名称空间中的元素,并构造具有相同本地名称但名称空间不同的新元素。发生这种情况是因为XSLT中的默认名称空间声明。所有新构造的元素都使用http://ns.adobe.com/air/application/16.0命名空间。

应用到您输入XML,结果是

<application xmlns="http://ns.adobe.com/air/application/16.0"> 
    <child id="1"/> 
    <child id="2"/> 
</application> 

您可以使用Ant的XSLT任务:

<xslt in="${temp.file1}" out="${temp.file1}" style="update-air-ns.xsl" /> 
+0

你可以解释一下xsl任务吗?我已经尝试了以上片段,因为它未能取代。 – jass 2015-02-06 12:14:34

+0

我想如果你想知道'xslt'任务如何工作,你需要参考文档。我已经解释了为什么'xmltask'不能做你想做的事情,并提供了一个你想要的解决方案。 *整合*解决方案是您的工作。 – Tomalak 2015-02-06 12:20:05

+0

好的命名空间代码+1。 – 2015-02-06 16:55:48

相关问题