Если вы установите xdmp:dialect="1.0-ml"
, то вы можете использовать шаблоны соответствия шаблонов для типов узлов JSON: object-node()
, array-node()
, number-node()
, boolean-node()
, null-node()
в дополнение возможность использовать XPath и сопоставлять шаблоны на основе имен узлов, таких как SomeProperty/LowProperty1
.
К сожалению, xsl:copy
выполняет глубокое копирование, что затрудняет преобразование, и для этих узлов JSON нет доступных конструкторов узлов XSLT.
Таким образом, преобразовать JSON в XML, HTML и текст довольно легко, но для того, чтобы создать желаемый преобразованный JSON, вам нужно либо преобразовать в json:object
, как продемонстрировано @wst, либо вы могли бы немного обмануть и просто сгенерировать текст в формате JSON.
Используя некоторые базовые шаблоны, которые соответствуют узлам JSON и генерируют его вывод текста JSON, вы можете добавить свой собственный специализированный шаблон для изменения значения SomeProperty/LowProperty1
:
let $stuff :=
document {
object-node {
"SomeProperty": object-node {
"LowProperty1":"some string",
"LowProperty2":"some string",
"LowProperty3": array-node { "some string 1", "some string 2"}
}
}
}
let $target := xdmp:unpath("/EvenLowerProperty/LowestProperty1", (), $stuff)
return
xdmp:xslt-eval(
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
xdmp:dialect="1.0-ml">
<xsl:output method="text"/>
<xsl:variable name="lcurly" select="'{'"/>
<xsl:variable name="rcurly" select="'}'"/>
<xsl:template match="node()">
<xsl:apply-templates select="." mode="name"/>
<xsl:apply-templates select="." mode="value"/>
</xsl:template>
<xsl:template match="array-node()/node()">
<xsl:apply-templates select="." mode="value"/>
</xsl:template>
<xsl:template match="node()" mode="name">
<xsl:if test="string(node-name(.))!=''">"<xsl:value-of select="node-name(.)"/>": </xsl:if>
</xsl:template>
<xsl:template match="text()" mode="value">
<xsl:text>"</xsl:text><xsl:value-of select="."/><xsl:text>"</xsl:text>
<xsl:if test="following-sibling::node()">, </xsl:if>
</xsl:template>
<xsl:template match="number-node() | boolean-node()" mode="value">
<xsl:value-of select="."/>
<xsl:if test="following-sibling::node()">, </xsl:if>
</xsl:template>
<xsl:template match="object-node()" mode="value">
<xsl:value-of select="$lcurly"/>
<xsl:apply-templates select="node()"/>
<xsl:value-of select="$rcurly"/>
<xsl:if test="following-sibling::node()">,</xsl:if>
</xsl:template>
<xsl:template match="array-node()/object-node()" mode="value">
<xsl:value-of select="$lcurly"/>
<xsl:apply-templates select="node()"/>
<xsl:value-of select="$rcurly"/>
<xsl:if test="following-sibling::node()">,</xsl:if>
</xsl:template>
<xsl:template match="array-node()" mode="value">
<xsl:value-of select="'['"/>
<xsl:apply-templates select="node()"/>
<xsl:value-of select="']'"/>
<xsl:if test="following-sibling::node()">,</xsl:if>
</xsl:template>
<xsl:template match="null-node()" mode="value">
<xsl:value-of select="'null'"/>
<xsl:if test="following-sibling::node()">, </xsl:if>
</xsl:template>
<xsl:template match="SomeProperty/LowProperty1">
<xsl:apply-templates select="." mode="name"/>
<xsl:text>"bar"</xsl:text>
<xsl:if test="following-sibling::node()">, </xsl:if>
</xsl:template>
</xsl:stylesheet>,
$stuff
)