Использовать / включать значение из другого узла
У меня есть XML- файл, например:
<area1>
<settings>
<setting name="to_include">value</setting>
</settings>
</area1>
<area2>
<settings>
<setting name="where_to_include">?????</setting>
</settings>
</area2>
Я хочу включить значение установочного узла "to_include" в качестве значения установочного узла "where_to_include". Как я мог сделать это, в чистом виде XML? XInclude? XPointer? XPath? XLink? Другой?
Я надеялся, что смогу сделать что-то вроде этого:
<area2>
<settings>
<setting name="where_to_include">
<xi:include href="SAMEFILE" xpointer="xpointer(/areas/area1/settings/setting[@name='debug'])">
<xi:fallback>FALLBACK VALUE</xi:fallback>
</setting>
</settings>
</area2>
Но с XInclude я не могу ссылаться на сам документ при его анализе.
1 ответ
Я не совсем понимаю вопрос, но я думаю, у меня есть идея, что вы имеете в виду. Это может быть не то, что вы после. Вы упоминаете XPointer и XInclude, которые кажутся мне излишними.
Вот решение XSLT (1.0). Таблица стилей принимает XML-файл, подобный тому, который вы задали в вопросе, и вставляет value
в течение ?????
, (Кстати, в вашем XML отсутствует элемент-обертка, поэтому он технически некорректен. Но я думаю, что понимаю, что вы имеете в виду. areas
как элемент документа, и вот как работает следующая таблица стилей. Возможно, вам придется настроить его так, чтобы он соответствовал XML, с которым вы на самом деле работаете.)
Вот таблица стилей:
<?xml version='1.0' encoding='UTF-8'?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="*">
<xsl:variable name="n" select="name (.)"/>
<xsl:element name="{$n}">
<xsl:for-each select="@*">
<xsl:copy-of select="."/>
</xsl:for-each>
<xsl:apply-templates select="node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="text()">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="/">
<xsl:element name="areas">
<xsl:apply-templates select="areas"/>
</xsl:element>
</xsl:template>
<xsl:template match="areas">
<xsl:apply-templates select="area1"/>
<xsl:apply-templates select="area2"/>
</xsl:template>
<xsl:template match="text()[parent::setting[ancestor::area2]]">
<xsl:apply-templates select="preceding::area1/settings/setting/text()"/>
</xsl:template>
</xsl:stylesheet>
По сути, таблица стилей просто копирует свой входной XML-документ, за исключением одного момента: setting
под area2
, он не копирует текст, но возвращается к area1
узел и копирует текст под его setting
, Вы можете подтвердить, что это работает, используя любой процессор XSLT, например, xsltproc (похоже, у вас есть некоторые нетривиальные функции XML в вашем распоряжении, так что это должно быть довольно просто). Просто внесите некоторые изменения в value
и запустите таблицу стилей в измененном XML-документе.