我有一个来自客户的XML,其中我不能确定名称空间。我需要替换一些属性的值。下面是输入XML示例:
<?xml version="1.0" encoding="UTF-8"?>
<NetworkSection xmlns:ovf="http://com/deployment/1.0">
<Network ovf:name="bridged"/>
</NetworkSection>
我想接收这样的XML:
<?xml version="1.0" encoding="UTF-8"?>
<NetworkSection xmlns:ovf="http://com/deployment/1.0">
<Network ovf:name="VM network"/>
</NetworkSection>
这里我尝试使用的XSL:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="utf-8"/>
<xsl:template match="NetworkSection/Network/@*[local-name()='name']">
<xsl:attribute name='name'>VM Network</xsl:attribute>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
问题是我丢失了属性名称空间。我不能在我的XSL中定义名称空间,因为它可能在不同的输入xml中有所不同,我只想更改属性值。
是否有可能在XSL中不指定命名空间而进行这样的替换?
这可以通过使用name()和namespace-uri()函数来实现。
<xsl:attribute name="{name()}" namespace="{namespace-uri()}">VM Network</xsl:attribute>
当您在XSLT中使用这一行时,您应该得到所需的输出
<Network ovf:name="VM network"/>
我对这个问题的首选方法是两步解决方案:首先规范化名称空间,然后进行"真正的"处理。这样做的好处是,管道中的规范化步骤可以被重用,无论您想要做什么后续处理,它总是会使后续处理更容易。