0

I just want to replace some XLML element values/attributes in LotusConnections-config.xml. Simple example:

<?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>

To modify hostWhitelist I tried the following stylesheet

<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>

This simple example shows a fundamental problem: I'd expect to have

<hostWhitelist enabled="false">
        <domain>admin_replace.com</domain>
</hostWhitelist>

replaced by ==XXXXX==. But after running xsltproc --novalid --nonet -o poc-out.xml poc-rules.xml poc-in.xml I got the same, unmodified input in poc-out.xml without any warnings or error messages. After a lot of researching, I found this question. To check if it matches my issue, I tried the workaround of replacing <xsl:template match="hostWhitelist"> by <xsl:template match="*[name()='hostWhitelist']"> and my substitution worked.

But I don't clearly understand which of the many namespaces from LotusConnections-config.xml I need to add, which prefix/suffix to set and why this even matters when --novalid --nonet is passed. It seems that http://www.ibm.com/LotusConnections-config is the namespace. I tried different combinations, for example

resulting in

# 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

I also tried

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xml="http://www.ibm.com/LotusConnections-config" version="1.0">

since I'm processing XML, but it raises errors too. The original example from the SO post

gave me no error but doesn't replace anything. The same for xpath-default-namespace="http://www.ibm.com/LotusConnections-config" in <xls:stylesheet (taken from here).

My questions are

  1. Which of the namespace are required and how (which key) do I set them in my stylesheet?
  2. Why do I need them, even when no remote/no validation is activated?
  3. Do I even have a change to make this work remotely? It seems that those scheme files doesn't exist in IBMs servers any more.

What partly worked

xmlstarlet has a placeholder _ for the default namespace. I assume it's fetched from the input xml file, since it offers drop-in replacement using CLI without style sheet file like xsltproc does.

# 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>

When using the edit option, this could be used for substitutions as well as fetching xpath values.

Lion
  • 16,606
  • 23
  • 86
  • 148

1 Answers1

0

Your XML declares a default namespace at the root config element as:

 xmlns="http://www.ibm.com/LotusConnections-config" 

This namespace is inherited by all descendants of config, unless overriden by another namespace declaration.

Nodes that are in namespace must be addressed by a name using a prefix that is bound to their namespace. Without a prefix, the expression will look for a node in no-namespace - and find nothing, in your example. Try:

<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>
michael.hor257k
  • 113,275
  • 6
  • 33
  • 51