Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xml 使用XSLT展开元素_Xml_Xslt - Fatal编程技术网

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>