【问题标题】:XML to HTML (XSLT): copy a node replacing some lines and adding new onesXML 到 HTML (XSLT):复制一个节点替换一些行并添加新行
【发布时间】:2011-12-18 15:22:55
【问题描述】:

我必须将 <script> 节点从 xml 复制到 html,但我需要动态替换其中的一些行,并添加新的行。所以我需要在整个节点复制时搜索和替换字符串。

XML 示例:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
id="slot" width="320" height="245">

   <script type="application/javascript"><![CDATA[
      var a = 2;
      var b = "abc";
      var c = new Array(0,0,0);
      alert("Input!");
   ]]></script>

   <!-- here svg drawing tags -->

</svg>

HTML 输出示例:

<html>
   <head>
      <title>Example!</title>

      <script type="application/javascript">
          var a = 2;                          <!---same as xml--->
          var b = "def";                      <!---modified--->
          var c = new Array(0,0,0);           <!---same as xml---> 
          alert("This is a new example!");    <!---modified---> 
          var new = "new var";                <!---new code--->             
      </script>
   </head> 
   <body>
   </body>
</html>

如果这很简单,我可以使用 XTLS 2.0。 我该怎么办?

【问题讨论】:

  • 这是在客户端还是在服务器上完成?如果它是在服务器上完成的,那么编写扩展代码可能比在标准 XSLT 中编写代码要简单得多。
  • 不幸的是它是在客户端完成的

标签: html xml xslt svg


【解决方案1】:

这种转变

<xsl:stylesheet version="2.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        xmlns:svg="http://www.w3.org/2000/svg"
        xmlns:my="my:my">
        <xsl:output omit-xml-declaration="yes" indent="yes"/>

        <xsl:param name="pSrcEdits">
         <line num="2" act="del"/>
         <line num="4" act="rep"
               newLine="var c = new Array(1,1,1);"/>
         <line num="5" act="ins"
               newLine="/* Inserted comment */"/>
        </xsl:param>

 <xsl:template match="node()|@*">
         <xsl:copy>
           <xsl:apply-templates select="node()|@*"/>
         </xsl:copy>
 </xsl:template>

 <xsl:template match="svg:script/text()">
  <xsl:variable name="vLines" select="tokenize(., '&#xD;?&#xA;')"/>

  <xsl:sequence select="my:editLines($vLines, $pSrcEdits/*)"/>
 </xsl:template>

 <xsl:function name="my:editLines" as="xs:string*">
  <xsl:param name="pLines" as="xs:string*"/>
  <xsl:param name="pCommands" as="element()*"/>

  <xsl:for-each select="$pLines">
   <xsl:variable name="vLineNum" as="xs:integer"
    select="position()"/>
   <xsl:variable name="vCommand"
     select="$pCommands[number(@num) eq  $vLineNum]"/>
   <xsl:sequence select="my:editSingle(., $vCommand)"/>
  </xsl:for-each>
 </xsl:function>

 <xsl:function name="my:editSingle" as="xs:string?">
  <xsl:param name="pLine" as="xs:string"/>
  <xsl:param name="pCommand" as="element()?"/>

  <xsl:sequence select=
  "if(not($pCommand))
     then concat($pLine, '&#xA;')
     else
      if($pCommand/@act eq 'del')
         then ()
         else
          if($pCommand/@act eq 'rep')
            then concat($pCommand/@newLine, '&#xA;')
            else (: 'ins' :)
              concat($pCommand/@newLine, '&#xA;', $pLine, '&#xA;')
  "/>

 </xsl:function>
</xsl:stylesheet>

应用于提供的 XML 文档时

<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
id="slot" width="320" height="245">

   <script type="application/javascript"><![CDATA[
      var a = 2;
      var b = "abc";
      var c = new Array(0,0,0);
      alert("Input!");
   ]]></script>

   <!-- here svg drawing tags -->

</svg>

产生想要的结果(执行所有命令并编辑脚本):

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
     id="slot"
     width="320"
     height="245">

   <script type="application/javascript">
       var b = "abc";
 var c = new Array(1,1,1);
 /* Inserted comment */
      alert("Input!");

</script>

   <!-- here svg drawing tags -->

</svg>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-10
    • 1970-01-01
    相关资源
    最近更新 更多