XPath - это язык выбора: он выбирает узлы или атомарные элементы из последовательности ввода, это язык выбора, чтобы сделать выбор по XML или иерархическим данным, поскольку SQL (обычно) является языком выбора с реляционными базами данных ,
Таким образом, вы можете исключить элементов выбора, но вы не можете обновления или изменения исходной последовательность. Можно сделать ограниченное преобразование (т. Е. Превратить строку в целое число), но это изменит выбранное значение, оно не изменит источник. Хотя XPath (а именно версия 2.0 и выше) может «создавать» атомные значения «на лету», он не может создавать новые элементы.
Это возможно и будет возвращать числовые значения в XPath 2.0:
/next/node/number(.)
Но это невозможно:
/next/node/(if (element4) then create-element(.) else .)
Однако в XSLT 2.0 и выше вы можете создать функцию, которая создает элементы. Как было сказано выше, XPath выбирает, и если вы хотите изменить документ, вы можете создать новый документ с использованием XSLT (значение T для Transformation).
Что-то вроде следующего (частично XSLT 2.0, вам нужно добавить заголовки):
<xsl:function name="f:create">
<xsl:param name="node" />
<xsl:param name="name" />
<xsl:choose>
<xsl:when test="name($node) = $name">
<xsl:element name="{if(number($node)) then 'int' else 'new'}">
<xsl:value-of select="$node" />
</xsl:element>
</xsl:when>
<xsl:otherwise><xsl:copy-of select="$node" /></xsl:otherwise>
</xsl:choose>
</xsl:function>
<xsl:template match="node">
<!-- now XPath, with help of XSLT function, can conditionally create nodes -->
<xsl:copy-of select="child::*/create(., 'element4')" />
</xsl:template>
<!-- boilerplate code, typically used to recursively copy non-matched nodes -->
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="@* | node()" />
</xsl:copy>
</xsl:template>
Обратите внимание, что, в то время как это показывает, как вы можете создать другой элемент, используя XPath и функцию XSLT, это не меняет источник, он изменяет выход. Кроме того, это не рекомендуется, так как в XSLT такая же картина более легко сделать, просто выполнив:
<!-- the more specific match -->
<xsl:template match="element4[number(.)]">
<new>
<int xmlns="foo.bar">
<xsl:value-of select="number(.)" />
</int>
</new>
<xsl:template>
<!-- XSLT will automatically fallback to this one if the former fails -->
<xsl:template match="element4">
<new><xsl:copy-of select="node()" /></new>
</xsl:template>
<!-- or this one, if both the former fail -->
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="@* | node()" />
</xsl:copy>
</xsl:template>
Не знаю, почему он не изменил элемент первого , но оба элементы должны как то же самое с 0 –
AFAIK, это невозможно используя только XPath. – Kachna
Качна, ты знаешь какой-нибудь другой способ сделать это? –