Автоматизация изменений LotusConnections-config.xml с помощью XSL/xsltproc: ничего не заменено неправильным пространством имен

Я просто хочу заменить некоторые значения/атрибуты элемента XLML в LotusConnections-config.xml. Простой пример:

<?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 без каких-либо предупреждений или сообщений об ошибках. После долгих исследований я нашел этот вопрос. Чтобы проверить, соответствует ли это моей проблеме, я попробовал обходной путь замены <xsl:template match="hostWhitelist"> на <xsl:template match="*[name()='hostWhitelist']">, и моя замена сработала.

Но я не совсем понимаю, какое из множества пространств имен из LotusConnections-config.xml мне нужно добавить, какой префикс/суффикс установить и почему это вообще имеет значение при передаче --novalid --nonet. Кажется, что http://www.ibm.com/LotusConnections-config - это пространство имен. Я пробовал разные комбинации, например

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

я тоже пробовал

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

так как я обрабатываю XML, но это тоже вызывает ошибки. Оригинальный пример из сообщения SO

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

Мои вопросы

  1. Какие пространства имен необходимы и как (какой ключ) установить их в моей таблице стилей?
  2. Зачем они мне нужны, даже если удаленная проверка/проверка не активированы?
  3. У меня даже есть изменение, чтобы заставить это работать удаленно? Кажется, что этих файлов схемы больше нет на серверах IBM.

Что частично сработало

xmlstarlet имеет заполнитель _ для пространства имен по умолчанию. Я предполагаю, что он получен из входного xml-файла, поскольку он предлагает вставную замену с использованием CLI без файла таблицы стилей, как это делает 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.


person Lion    schedule 05.03.2020    source источник


Ответы (1)


Ваш XML объявляет пространство имен по умолчанию в корневом элементе config следующим образом:

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

Это пространство имен наследуется всеми потомками config, если оно не переопределено другим объявлением пространства имен.

Узлы, находящиеся в пространстве имен, должны быть адресованы по имени с использованием префикса, привязанного к их пространству имен. Без префикса выражение будет искать узел в пространстве без имен - и ничего не найдет в вашем примере. Пытаться:

<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>
person michael.hor257k    schedule 05.03.2020