使用XSLT将XML转换为XML(删除、添加、更改)



我必须使用XSLT从一个XML(XHTML)文件转换到另一个文件。转换的规则是:

  1. <div id="ta12" class="bl" style="dis:bl">必须替换为<div class="pass" value="50">
  2. id="t0b"one_answers"t1b"的值必须分别替换为id="ta0b8"one_answers"ta3b8"
  3. <input type="radio" name="o0" id="t0"/>必须替换为<input type="radio" name="key0b8" value="0" id="ta0q" class="block" />(同样在文件中)

输入文件:

    <?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-type" content="text/html;  charset=utf-8" />
    </head>  
    <body>
      <div class="iDev">
      <div id="ta12" class="bl" style="dis:bl"></div>
        <div class="q">
          <div id="t0b" class="block">1<span style="color">TEXT1</span>
          </div><br />
          T <input type="radio" name="o0" id="t0"/> 
          F <input type="radio" name="op0" id="f0"/>
          <div id="sfb"></div>
        </div><br />
        <div class="q">
          <div id="t1b" class="block">2<span style="color">TEXT2</span>
          </div><br />
          T <input type="radio" name="o1" id="t1" /> 
          F <input type="radio" name="op1" id="f1" />
          <div id="sfb"></div>
        </div>
      </div>
    </body>
    </html>

输出文件:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html;  charset=utf-8" />
</head>
<body>
  <div class="iDev">
  <div class="pass" value="50"></div>
    <div class="q">
      <div id="ta0b8" class="block">1<span style="color">TEXT1</span>
      </div><br />
      T<input type="radio" name="key0b8" value="0" id="ta0q" />
      F<input type="radio" name="key0b8" value="1" id="ta1q" />
      <div id="sfb"></div>
    </div><br />
    <div class="q">
      <div id="ta3b8" class="block">2 <span style="color">TEXT2</span>
      </div><br />
      T<input type="radio" name="key3b8" value="0" id="ta0q3" />
      F<input type="radio" name="key3b8" value="1" id="ta1q3" />
      <div id="sfb"></div>
    </div>
  </div>
</body>
</html>

在我的XSLT中,我创建了一个包含整个输入文件的标识模板,然后我尝试进行所需的修改。我可以通过-完成第一项任务

<xsl:template match="xhtml:div[@id='ta12']">
  <xsl:attribute name="class">pa</xsl:attribute>
  <xsl:attribute name="value">10</xsl:attribute>
</xsl:template>

在输出中,它会生成所需的Div标记,但会删除<div class="iDev">标记。有人能告诉我从给定的输入中产生所需输出的解决方案吗。谢谢你!

我将讨论您的第一条规则,因为这似乎是您问题的焦点。如果您需要有关规则2和3的帮助,请分别提出问题。

通常,XSLT1.0复制元素(非深度)的解决方案模式如下所示。我所说的非深度,是指删除任何子节点。

清单1

<xsl:template match="some-element-pattern">
  <xsl:copy>
   <xsl:copy-of select="@*" />
   <xsl:attribute name="my-attrib-to-set">value-to-set</xsl:attribute>
  </xsl:copy>
</xsl:template>

或者,如果存在直接复制以外的其他属性处理潜力,则可以用xsl:apply-templates替换xsl:copy-of。xsl:apply-templates是更通用的表单。

因此,将此解决方案模式应用于您的案例,您需要的模板是。。。

清单2

<xsl:template match="xhtml:div[@id='ta12']">
  <xsl:copy>
   <xsl:copy-of select="@*" />
   <xsl:attribute name="class">pa</xsl:attribute>
   <xsl:attribute name="value">10</xsl:attribute>
  </xsl:copy>
</xsl:template>

注:。在以前的解决方案中,我可能给了你这个低效的模板。。。

清单3

<xsl:template match="xhtml:div[@id='ta12']">
  <xsl:copy>
   <xsl:apply-templates select="@*[not(@class)]" />
   <xsl:attribute name="class">pa</xsl:attribute>
  </xsl:copy>
</xsl:template>

我现在意识到这是错误的。谓词not(@class)毫无意义,并且总是返回true,因为当焦点项是属性时,attribute::axis总是返回空序列。清单3背后的想法是,在匹配的输入div元素具有class属性的情况下,消除对class属性的无关处理。如果您真的想在XSLT1.0中获得比清单2更高的效率,您可以按照清单4来做,但代码有些难看,我不确定它是否值得

清单4

<xsl:template match="xhtml:div[@id='ta12']">
  <xsl:copy>
   <xsl:apply-templates select="@*[local-name()!='class']
                                  [local-name()!='value']" />
   <xsl:attribute name="class">pa</xsl:attribute>
   <xsl:attribute name="value">10</xsl:attribute>
  </xsl:copy>
</xsl:template>

清单4只适用于null名称空间中的类和值。如果有问题的属性在名称空间中,则需要进行一些替换。

这是你的最后一个选择。如果您准备牺牲xsl:copy的通用性,并想吸取AttributeValueTemplates的精华,那么可以使用清单5。在清单5中,您可以根据需要将"pa"one_answers"va"替换为"属性值模板"。该解决方案的另一个缺点是,现在必须确保@class和@value属性不在子xsl:apply-templates中处理,否则它们将重写预期的文字值,而不仅仅是一种效率度量。

清单5

<xsl:template match="xhtml:div[@id='ta12']">
  <xhtml:div class="pa" value="va">
   <xsl:apply-templates select="@*[local-name()!='class']
                                  [local-name()!='value']" />
  </xhtml:div>
</xsl:template>

最后,我知道您只对XSLT1.0感兴趣,但为了好玩,我将介绍XSLT2.0的一般解决方案模式。如清单6所示。

清单6

<xsl:template match="some-element-pattern">
  <xsl:copy>
   <xsl:apply-templates select="@* except @my-attrib-to-set" />
   <xsl:attribute name="my-attrib-to-set">value-to-set</xsl:attribute>
  </xsl:copy>
</xsl:template>

相关内容

  • 没有找到相关文章