Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/12.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 XSL转换问题_Xml_Xslt - Fatal编程技术网

Xml XSL转换问题

Xml XSL转换问题,xml,xslt,Xml,Xslt,我在使用XSL样式表转换XML时遇到了一些问题,在XSL样式表中,输出需要具有与XML文件中的结构不同的结构 简单的例子: 输入: <p>This is <b>bold text</b>, <i>italic text</i> and normal text</p> 这是粗体文本、斜体文本和普通文本 我的问题是输入中的字符格式是嵌套的,它们不能嵌套在输出中(没有任何明显格式的文本被视为具有“正常”字符样式,并且必须在输出

我在使用XSL样式表转换XML时遇到了一些问题,在XSL样式表中,输出需要具有与XML文件中的结构不同的结构

简单的例子:

输入:

<p>This is <b>bold text</b>, <i>italic text</i> and normal text</p>
这是粗体文本、斜体文本和普通文本

我的问题是输入中的字符格式是嵌套的,它们不能嵌套在输出中(没有任何明显格式的文本被视为具有“正常”字符样式,并且必须在输出中这样定义)

有效输出:

<p>
   <c style="normal">This is </c>
   <c style="bold">bold text</c>
   <c style="normal">, </c>
   <c style="italic">italic text</c>
   <c style="normal"> and normal text</c>
</p>

这是
粗体文本
, 
斜体文本
和普通文本

一个人是如何做到这一点的

我可以确定如何设置粗体和斜体格式,但无法确定如何在从其他格式之一返回后启动新的“正常”格式,因为我无法保存当前状态。请注意,“粗体”或“斜体”后面不一定是“正常”格式,它是在粗体或斜体之前激活的任何格式,因此我真正想要的是某种方式来记住我当前使用的格式,以便在使用其他字符格式后可以再次定义它

请注意,以下(明显)样式无效,因为它包含嵌套格式。我在创建此样式时没有问题:

<p>
   <c style="normal">This is
      <c style="bold">bold text</c>
      , 
      <c style="italic">italic text</c>
      and normal text
   </c>
</p>

这是
粗体文本
, 
斜体文本
和普通文本


我将通过为元素定义模板而不是为元素定义模板,而是为元素中的文本节点定义模板,使用每个文本节点的祖先来确定它应该是什么样式:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output indent="yes" />

  <xsl:template match="p">
    <p><xsl:apply-templates /></p>
  </xsl:template>

  <!-- direct text nodes under a p become "normal" -->
  <xsl:template match="p/text()">
    <c style="normal"><xsl:value-of select="." /></c>
  </xsl:template>

  <!-- text nodes under both an i and a b become bold-italic -->
  <xsl:template match="b//i/text() | i//b/text()" priority="2">
    <c style="bold-italic"><xsl:value-of select="." /></c>
  </xsl:template>

  <!-- text nodes under a b but not an i become bold -->
  <xsl:template match="b/text()">
    <c style="bold"><xsl:value-of select="." /></c>
  </xsl:template>

  <!-- text nodes under an i but not a b become italic -->
  <xsl:template match="i/text()">
    <c style="italic"><xsl:value-of select="." /></c>
  </xsl:template>

</xsl:stylesheet>
当您应用模板时,决定传递什么作为
$style
参数的逻辑可能会非常复杂


如果您仅限于XSLT 1.0,那么您没有隧道参数,因此您必须在所有级别显式显示
param
with param
元素,但这应该让您了解如何继续操作。

这应该可以解决您的问题:

'<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="xml" indent="yes" encoding="UTF-8"/>
  <!-- identity-copy template (see http://en.wikipedia.org/wiki/Identity_transform#Using_XSLT ) -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
  <!-- transformation b - bold -->
  <xsl:template match="b">
    <c style="bold">
      <xsl:apply-templates/>
    </c>
  </xsl:template>
  <!-- transformation i - italic -->
  <xsl:template match="i">
    <c style="italic">
      <xsl:apply-templates/>
    </c>
  </xsl:template>
  <!-- if text does not have b or i as an ancestor, it is normal -->
  <xsl:template match="text()[not(ancestor::b) and not(ancestor::i)]">
    <c style="normal">
      <xsl:copy/>
    </c>
  </xsl:template>
</xsl:stylesheet>
'

下面是groovy脚本,展示了它是如何工作的:

请您更正输入,使其表示格式正确的XML好吗?并且是不平衡的。如果输入XML格式不正确,那么谈论XSLT是没有意义的。
'<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="xml" indent="yes" encoding="UTF-8"/>
  <!-- identity-copy template (see http://en.wikipedia.org/wiki/Identity_transform#Using_XSLT ) -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
  <!-- transformation b - bold -->
  <xsl:template match="b">
    <c style="bold">
      <xsl:apply-templates/>
    </c>
  </xsl:template>
  <!-- transformation i - italic -->
  <xsl:template match="i">
    <c style="italic">
      <xsl:apply-templates/>
    </c>
  </xsl:template>
  <!-- if text does not have b or i as an ancestor, it is normal -->
  <xsl:template match="text()[not(ancestor::b) and not(ancestor::i)]">
    <c style="normal">
      <xsl:copy/>
    </c>
  </xsl:template>
</xsl:stylesheet>