假设我有一些包含这样的xml输入。 w15
可能还有其他内容,例如w
,w1
。
<w15:presenceInfo w15:providerId="None" w15:userId="First Last"/>
有人知道替换的最佳方式是什么?
w15:userId =&#34; First Last&#34; - &GT; w15:userId =&#34;其他东西&#34;
我不想使用像sed
这样的东西,因为我害怕更换一些不应该替换的东西。
有人知道xslt中的解决方案吗?
有人知道lxml(http://lxml.de/)中的解决方案吗?
其他没有使用xslt / lxml的解决方案?
哪一个最适合解决这个问题? (对于sed
,只需要一行替换&#34; First Last&#34; with&#34; Something&#34;(假设输入xml
文件中没有任何内容不会使sed
无法正常工作。)是否有一个尊重xml
规范的解决方案,但是只有一行代码?
答案 0 :(得分:2)
在XSLT 3.0中,它非常接近您正在寻找的单行:
<xsl:transform version="3.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="@*:userId[.='First Last']">
<xsl:attribute name="{local-name()}" namespace="{namespace-uri()}">Something else</xsl:attribute>
</xsl:template>
</xsl:transform>
答案 1 :(得分:1)
让我们从好消息开始吧。您可以使用替换属性的值
使用匹配的模板,无论名称空间如何,都使用特定名称
属性(@*
)与谓词中的特定local-name()
。
下面给出的脚本包含2个此类模板,适用于providerId
和userId
。
但坏消息是你不能完全“闭眼”命名空间 用过的。有关XSLT命名空间处理的规则要求使用XSLT 脚本必须包含所有使用的命名空间的定义。
请注意,下面的脚本包含这样的定义:xmlns:w15="urn:dummy_15"
,通常放在脚本的根标记中。
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:w15="urn:dummy_15">
<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="@*[local-name() = 'providerId']">
<xsl:attribute name="{name()}">
<xsl:value-of select="'Something else 1'"/>
</xsl:attribute>
</xsl:template>
<xsl:template match="@*[local-name() = 'userId']">
<xsl:attribute name="{name()}">
<xsl:value-of select="'Something else 2'"/>
</xsl:attribute>
</xsl:template>
</xsl:transform>
有关工作示例,请参阅http://xsltransform.net/gVrtEmW
所以你可以拥有一个“样本”XSLT脚本,没有名称空间,但是在最后 那一刻,在实际运行脚本之前,你必须要看看 什么名称空间包含您的源XML文件并添加使用的规范 脚本的名称空间。