XSL使用第一个正则表达式的输出写入第二个正则表达式,并使用第二个正则表达式命中的祖先覆盖子字符串

时间:2015-04-17 17:02:15

标签: xml xslt

我有这样的XML:

<c hw="A">
  <e hw="aardvark">
    <d t="see &lt;a onclick=&quot;goToEntryWithId('2319')&quot;&gt;mammals&lt;/a&gt; for more details."/>
  </e>
</c>

使用XML格式:

<c hw="M">
  <e hw="mammals" i="2319">
    <d t="Here's useful info about mammals."/>
  </e>
</c>

我正在根据标签将XML分成多个HTML文件,我想将onclick更改为具有适当目标的href。

期望的输出:

<p>See <a href="M.html#2319">mammals</a> for more details.

我需要以某种方式

1)找到包含####,

的onclick表达式的匹配项

2)获取onclick中引用的数字(####),并在XML文档的其他位置找到它,隐藏在<e i="####">

之类的地方

3)在数字

中找到搜索结果的祖先:: c [@hw]父

4)用简单的href="[filename].html#[####]"

替换onclick表达式

5)对XML中的每个onclick="goToEntryWithId('####')次事件执行此操作,包括同一行上的多次点击。

我有什么想法可以实现这个目标?

1 个答案:

答案 0 :(得分:0)

您还没有说过要使用哪个版本的XSLT和哪个XSLT处理器,但假设您可以使用Saxon 9.6 HE至少可以使用XPath 3.0 parse-xml-fragment函数来解析编码的标记到节点中然后进一步处理它们,只需要正则表达式来查找和提取onclick属性。

基于此我创建了一个示例输入

<root>
  <references>
    <c hw="A">
      <e hw="aardvark">
        <d t="see &lt;a onclick=&quot;goToEntryWithId('2319')&quot;&gt;mammals&lt;/a&gt; for more details."/>
      </e>
    </c>
  </references>
  <content>
    <c hw="M">
      <e hw="mammals" i="2319">
        <d t="Here's useful info about mammals."/>
      </e>
    </c>
  </content>
</root>

和样式表

<xsl:stylesheet
  version="3.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  exclude-result-prefixes="xs">

<xsl:param name="pattern" as="xs:string">^goToEntryWithId\('[0-9]+'\)$</xsl:param>

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

<xsl:key name="id" match="content/c/e" use="@i"/>

<xsl:variable name="main-doc" select="/"/>

<xsl:template match="/">
  <html>
    <body>
      <xsl:apply-templates select="root/references//@t"/>
    </body>
  </html>
</xsl:template>

<xsl:template match="references/c/e/d/@t">
  <p>
    <xsl:apply-templates select="parse-xml-fragment(.)/node()"/>
  </p>
</xsl:template>

<xsl:template match="a[@onclick[matches(., $pattern)]]">
  <xsl:variable name="id" select="replace(@onclick, '[^0-9]+', '')"/>
  <xsl:variable name="referenced-c" select="key('id', $id, $main-doc)/ancestor::c[@hw]"/>
  <a href="{$referenced-c/@hw}.html#{$id}">
    <xsl:apply-templates/>
  </a>
</xsl:template>

</xsl:stylesheet>

使用Saxon 9.6 HE或Saxon 9.5 EE(参见http://xsltransform.net/94hvTzw)创建输出

<html>
   <body>
      <p>see <a href="M.html#2319">mammals</a> for more details.
      </p>
   </body>
</html>