XSLT:在多个级别上用脚本替换 div

XSLT: Replacing div with script on multiple levels

我正在尝试用任何级别的脚本标签替换某些 div 标签。 div 中设置为显示 none 的代码是我需要的(丢弃两个外部 divs),并且该代码中的 divs 具有"is-script" 的 class 必须替换为脚本,同时保留其属性和节点。 代码外观的一些示例:

 <div data-type="embed">
    <div style="display:none;">
        <div class="is-script" src="http://example.js"></div>
    </div>
</div>

<div data-type="embed">
    <div style="display:none;">
        <div class="is-script" src="http://example1.js"></div>
        <div class="is-script" src="http://example2.js"></div>
    </div>
</div>

<div data-type="embed">
    <div style="display:none;">
        <div>
            <div class="is-script" src="http://example.js"></div>
        </div>
    </div>
</div>

<div data-type="embed">
    <div style="display:none;">
        <div>
            <div class="is-script" src="http://example1.js"></div>
            <div class="is-script" src="http://example2.js"></div>
        </div>
    </div>
</div>

<div data-type="embed">
    <div style="display:none;">
        <div>
            <div class="is-script" src="http://example1.js"></div>
            <div class="is-script">some inline javascript</div>
        </div>
    </div>
</div>

<div data-type="embed">
    <div style="display:none;">
        <iframe src="http://example.html" width="100%" height="400px"></iframe>
    </div>
</div>

xsl 正在解析的实际 json:

<div data-type=\"embed\" style=\"width:545px;height:200px;background-color:#ccc;\">HTML EMBED
    <div style=\"display:none;\">
        <div class=\"is-script\">console.log(\"test1\");</div>
    </div>
</div>

<div data-type=\"embed\" style=\"width:545px;height:200px;background-color:#ccc;\">HTML EMBED
    <div style=\"display:none;\">
        <div>
            <div class=\"is-script\">console.log(\"test2\");</div>
        </div>
    </div>
</div>

<div data-type=\"embed\" style=\"width:545px;height:200px;background-color:#ccc;\">HTML EMBED
    <div style=\"display:none;\">
        <div class=\"is-script\" src=\"example.js\"></div>
    </div>
</div>

<div data-type=\"embed\" style=\"width:545px;height:200px;background-color:#ccc;\">HTML EMBED
    <div style=\"display:none;\">
        <div>
            <div class=\"is-script\" src=\"example.js\"></div>
        </div>
    </div>
</div>

<div data-type=\"embed\" style=\"width:545px;height:200px;background-color:#ccc;\">HTML EMBED
    <div style=\"display:none;\">
        <div>
            <div class=\"is-script\" src=\"example1.js\"></div>
            <div class=\"is-script\" src=\"example2.js\"></div>
            <div class=\"is-script\" src=\"example3.js\"></div>
        </div>
    </div>
</div>

想要的结果:

<script class="is-script" src="http://example.js"></script>


<script class="is-script" src="http://example1.js"></script>
<script class="is-script" src="http://example2.js"></script>


<div>
    <script class="is-script" src="http://example.js"></script>
</div>


<div>
    <script class="is-script" src="http://example1.js"></script>
    <script class="is-script" src="http://example2.js"></script>
</div>


<div>
    <script class="is-script" src="http://example1.js"></script>
    <script class="is-script">some inline javascript</script>
</div>


<iframe src="http://example.html" width="100%" height="400px"></iframe>

当前结果:

<script class="was-script-tag">console.log("test1");</script>

<div>
    <div class="was-script-tag">console.log("test2");</div>
</div>

<script class="was-script-tag" src="/templates/v1/js/sticky_article_v7.js?v0"></script>

<div>
    <div class="was-script-tag" src="/templates/v1/js/sticky_article_v7.js?v1"></div>
</div>

<div>
    <div class="was-script-tag" src="/templates/v1/js/sticky_article_v7.js?v2"></div>
    <div class="was-script-tag" src="/templates/v1/js/sticky_article_v7.js?v2"></div>
    <div class="was-script-tag" src="/templates/v1/js/sticky_article_v7.js?v2"></div>
</div>

我的 xsl:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

    <xsl:output method="html" indent="yes"/>


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

    <xsl:template match="div[@data-type='embed' or parent::div[@data-type='embed']]">
        <xsl:apply-templates />
    </xsl:template>

    <xsl:template match="div[@class='is-script']">
        <script>
            <xsl:apply-templates select="@*|node()"/>
        </script>
    </xsl:template>

</xsl:stylesheet> 

所以基本上删除了两个外部 divs,并保持内部的所有内容不变,除了 divs with class of "is-script" 必须重命名为脚本。外面的两个 div 将始终相同。

我对xsl有基本的了解,但这是我做不到的事情。 使用 xslt 2.

您可以从身份模板开始,它将复制所有现有节点而不做任何更改

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

然后,要忽略 "outer two divs",您可以像这样添加一个覆盖模板:

<xsl:template match="div[@data-type='embed' or parent::div[@data-type='embed']]">
  <xsl:apply-templates />
</xsl:template>

这会忽略 div 数据类型为嵌入的元素或其直接子元素 div。

然后要将 "is-script" div 更改为 script 元素,您可以添加另一个模板

<xsl:template match="div[@class='is-script']">
  <script>
    <xsl:apply-templates select="@*|node()"/>
  </script>
</xsl:template>

试试这个 XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="div[@data-type='embed' or parent::div[@data-type='embed']]">
    <xsl:apply-templates />
  </xsl:template>

  <xsl:template match="div[@class='is-script']">
    <script>
      <xsl:apply-templates select="@*|node()"/>
    </script>
  </xsl:template>
</xsl:stylesheet>