XSLT: создать узел, если он не существует?
как я могу использовать XSLT для создания узлов, если они не существуют? Мне нужно вставить узел под , но если узел не существует, то мне также нужно создать его.
например.
вход (узел группы существует):
<story>
<group>
<overhead>
<l1>overhead</l1>
</overhead>
<headline>
<l1>headline</l1>
</headline>
</group>
<text>
<lines>
<l1>line</l1>
</lines>
</text>
</story>
выход:
<story>
<group>
<sectionhead />
<overhead>
<l1>overhead</l1>
</overhead>
<headline>
<l1>headline</l1>
</headline>
</group>
<text>
<lines>
<l1>line</l1>
</lines>
</text>
</story>
вход (узел группы не существует):
<story>
<text>
<lines>
<l1>line</l1>
</lines>
</text>
</story>
выход:
<story>
<group>
<sectionhead />
</group>
<text>
<lines>
<l1>line</l1>
</lines>
</text>
</story>
3 ответов
попробуйте перевести правила в вашем описании проблемы непосредственно в правила шаблона:
" мне нужно вставить узел <sectionhead>
под <group>
"
<xsl:template match="group">
<group>
<sectionhead/>
<xsl:apply-templates/>
</group>
</xsl:template>
"но если <group>
узел не существует, тогда я должен создать."
<xsl:template match="story[not(group)]">
<story>
<group>
<sectionhead/>
</group>
<xsl:apply-templates/>
</story>
</xsl:template>
вот полное решение, которое переопределяет правило идентификации / шаблон для любого story
элемент, который не имеет group
ребенок:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="story[not(group)]">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<group>
<sectionhead />
</group>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="group[not(sectionhead)]">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<sectionhead />
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
когда он применяется к предоставленному XML-документу (без group
):
<story>
<text>
<lines>
<l1>line</l1>
</lines>
</text>
</story>
получается нужный, правильный результат:
<story>
<group>
<sectionhead/>
</group>
<text>
<lines>
<l1>line</l1>
</lines>
</text>
</story>
при применении к первому XML-документу (имея group
что нет sectionhead
ребенок):
<story>
<group>
<overhead>
<l1>overhead</l1>
</overhead>
<headline>
<l1>headline</l1>
</headline>
</group>
<text>
<lines>
<l1>line</l1>
</lines>
</text>
</story>
это же преобразование снова дает желаемый, правильный результат:
<story>
<group>
<sectionhead/>
<overhead>
<l1>overhead</l1>
</overhead>
<headline>
<l1>headline</l1>
</headline>
</group>
<text>
<lines>
<l1>line</l1>
</lines>
</text>
</story>
<xsl:for-each select="//story/group">
<sectionhead />
<xsl:copy-of select="." />
</xsl:for-each>
<xsl:for-each select="//story/text">
<group><sectionhead /></group>
<xsl:copy-of select="." />
</xsl:for-each>
двухфазный-ОК ?