使用XSL / xsltproc自动进行LotusConnections-config.xml修改:不能用错误的名称空间代替

问题描述 投票:0回答:1

我只想替换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)。

我的问题是

  1. 哪个名称空间是必需的,以及如何(哪个键)在我的样式表中设置它们?
  2. 即使没有激活远程/验证也为什么需要它们?
  3. 我甚至可以进行更改以使其远程工作吗?这些方案文件似乎在IBM的服务器中不再存在。

部分起作用

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值。
xml xslt xslt-1.0 ibm-connections
1个回答
0
投票
您的XML在根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>

© www.soinside.com 2019 - 2024. All rights reserved.