Xml 使用XSLT展开元素
我需要取消包装(或取消嵌套)当前包装在段落标记中的某些元素(如Xml 使用XSLT展开元素,xml,xslt,Xml,Xslt,我需要取消包装(或取消嵌套)当前包装在段落标记中的某些元素(如标记)。但它们不应该是这样,我需要能够使用XSLT纠正这一点 它可能看起来像这样,例如: <paragraph>Some text here with a <bold>word</bold> in bold, for example, and then an image: <image href="whatever.png"></image> and poss
标记)。但它们不应该是这样,我需要能够使用XSLT纠正这一点
它可能看起来像这样,例如:
<paragraph>Some text here with a <bold>word</bold> in bold, for example, and then an image:
<image href="whatever.png"></image>
and possibly some more text here.
</paragraph>
例如,此处的某些文本带有粗体字,然后是图像:
这里可能还有更多的文字。
在这里,我需要将文本(包括内联的粗体标记)分离为一个段落,后面是单独的图像,而不是在段落内部,然后在末尾为文本添加一个新段落。像这样:
<paragraph>Some text here with a <bold>word</bold> in bold, for example, and then an image:</paragraph>
<image href="whatever.png"></image>
<paragraph>and possibly some more text here.</paragraph>
例如,此处的某些文本带有粗体字,然后是图像:
这里可能还有更多的文字。
但我不知道该怎么做。我可以为每个节点这样做,但是粗体标记也会放在一个单独的段落中,我不希望这样
请注意,标记只是一个示例。列表、表格等也会出现同样的情况,基本上问题是它们已经被包装在段落标记中,而它们本不应该被包装。因此,文本(包括粗体、斜体等内联元素)需要保留为一个块中的段落,但其他类型的元素、图像、表格等需要从中取消包装,当然仍然保留内容的正确顺序
任何想法都值得赞赏 假设XSLT 3.0可以
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs">
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* , node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="paragraph">
<xsl:for-each-group select="node()" group-adjacent="boolean(self::image | self::table | self::list)">
<xsl:choose>
<xsl:when test="current-grouping-key()">
<xsl:apply-templates select="current-group()"/>
</xsl:when>
<xsl:otherwise>
<xsl:copy select="..">
<xsl:apply-templates select="current-group()"/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
在XSLT 1.0中,以下是一个使用同级递归来解决此问题的示例:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:template match="@* | node()" name="identity">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="paragraph">
<xsl:apply-templates select="node()[1]"/>
</xsl:template>
<xsl:template match="paragraph/image | paragraph/table | paragraph/list">
<xsl:call-template name="identity"/>
<xsl:apply-templates select="following-sibling::node()[1]"/>
</xsl:template>
<xsl:template match="paragraph/node()[not(self::image | self::table | self::list)]">
<paragraph>
<xsl:call-template name="identity"/>
<xsl:apply-templates select="following-sibling::node()[1][not(self::image | self::table | self::list)]" mode="copy"/>
</paragraph>
<xsl:apply-templates select="following-sibling::node()[self::image | self::table | self::list][1]"/>
</xsl:template>
<xsl:template match="paragraph/node()[not(self::image | self::table | self::list)]" mode="copy">
<xsl:call-template name="identity"/>
<xsl:apply-templates select="following-sibling::node()[1][not(self::image | self::table | self::list)]" mode="copy"/>
</xsl:template>
</xsl:stylesheet>
图像、列表
、表格
元素是否总是直接指向段落
元素的子元素?或者可以有进一步的嵌套,比如这个粗体文本。
?您使用或可以使用哪个版本的XSLT?回答得很好,谢谢!当使用XSLT2.0和Saxon进行测试时,它可以工作。唯一的问题是,在这种情况下,我很可能不得不使用XSLT1.0,我忘了这么说。有没有可能1.0有一个等价物?@AndersSvensson,我添加了一个XSLT1.0示例来执行同级递归(它从段落/节点()[1]
开始,然后沿着下面的同级轴收集属于一起的节点,并直接输出图像
,表格
和列表
元素)。
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:template match="@* | node()" name="identity">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="paragraph">
<xsl:apply-templates select="node()[1]"/>
</xsl:template>
<xsl:template match="paragraph/image | paragraph/table | paragraph/list">
<xsl:call-template name="identity"/>
<xsl:apply-templates select="following-sibling::node()[1]"/>
</xsl:template>
<xsl:template match="paragraph/node()[not(self::image | self::table | self::list)]">
<paragraph>
<xsl:call-template name="identity"/>
<xsl:apply-templates select="following-sibling::node()[1][not(self::image | self::table | self::list)]" mode="copy"/>
</paragraph>
<xsl:apply-templates select="following-sibling::node()[self::image | self::table | self::list][1]"/>
</xsl:template>
<xsl:template match="paragraph/node()[not(self::image | self::table | self::list)]" mode="copy">
<xsl:call-template name="identity"/>
<xsl:apply-templates select="following-sibling::node()[1][not(self::image | self::table | self::list)]" mode="copy"/>
</xsl:template>
</xsl:stylesheet>