我只想替换LotusConnections-config.xml
中的某些XLML元素值/属性。简单的例子:
<?xml version="1.0" encoding="UTF-8"?><!-- Copyright IBM Corp. 2001, 2017 All Rights Reserved. -->
<config buildlevel="IC6.0_20170314_1305" id="LotusConnections" xmlns="http://www.ibm.com/LotusConnections-config" xmlns:sloc="http://www.ibm.com/service-location" xmlns:tns="http://www.ibm.com/LotusConnections-config" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.ibm.com/LotusConnections-config LotusConnections-config.xsd">
<hostWhitelist enabled="false">
<domain>admin_replace.com</domain>
</hostWhitelist>
<!-- ... -->
</config>
要修改hostWhitelist
,我尝试了以下样式表
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!-- Copies every input node unchanged -->
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*" />
</xsl:copy>
</xsl:template>
<xsl:template match="hostWhitelist">
==XXXXX==
</xsl:template>
</xsl:stylesheet>
此简单示例显示了一个基本问题:我希望有
<hostWhitelist enabled="false">
<domain>admin_replace.com</domain>
</hostWhitelist>
由==XXXXX==
代替。但是在运行xsltproc --novalid --nonet -o poc-out.xml poc-rules.xml poc-in.xml
之后,我在poc-out.xml
中得到了相同的未修改输入,没有任何警告或错误消息。经过大量研究,我发现this question。为了检查它是否与我的问题匹配,我尝试用the workaround将<xsl:template match="hostWhitelist">
替换为<xsl:template match="*[name()='hostWhitelist']">
,并且我的替换有效。
但是我不清楚我需要添加LotusConnections-config.xml
中的许多名称空间中的哪个,设置哪个前缀/后缀,以及为什么在传递--novalid --nonet
时这很重要。似乎http://www.ibm.com/LotusConnections-config
是名称空间。我尝试了不同的组合,例如
导致
# xsltproc --novalid --nonet -o poc-out.xml poc-rules.xml poc-in.xml
compilation error: file poc-rules.xml line 1 element stylesheet
xsltParseStylesheetProcess : document is not a stylesheet
我也尝试过
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xml="http://www.ibm.com/LotusConnections-config" version="1.0">
因为我正在处理XML,但它也会引发错误。来自SO帖子的原始示例
没有给我任何错误,但不替换任何内容。对于xpath-default-namespace="http://www.ibm.com/LotusConnections-config"
中的<xls:stylesheet
也是如此(取自here)。
xmlstarlet
具有占位符_
for the default namespace。我假定它是从输入xml文件中提取的,因为它使用CLI而不是[[style sheet文件就可以像xsltproc
那样提供直接替换功能。
# xmlstarlet select -t -c "/_:config/_:hostWhitelist" /tmp/lc-checkout/LotusConnections-config.xml
<hostWhitelist xmlns="http://www.ibm.com/LotusConnections-config" xmlns:sloc="http://www.ibm.com/service-location" xmlns:tns="http://www.ibm.com/LotusConnections-config" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" enabled="false">
<domain>admin_replace.com</domain>
[当使用edit
选项时,它可以用于替换以及获取xpath值。
config
元素处将默认名称空间声明为:
xmlns="http://www.ibm.com/LotusConnections-config"
此命名空间由config
的所有后代继承,除非被另一个命名空间声明覆盖。名称空间中的节点必须使用名称绑定到其名称空间的名称来寻址。如果没有前缀,表达式将在no-namespace中寻找一个节点-在您的示例中什么也找不到。试试:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:cfg="http://www.ibm.com/LotusConnections-config"> <!-- Copies every input node unchanged --> <xsl:template match="node() | @*"> <xsl:copy> <xsl:apply-templates select="node() | @*" /> </xsl:copy> </xsl:template> <xsl:template match="cfg:hostWhitelist"> ==XXXXX== </xsl:template> </xsl:stylesheet>