0

我有一个 nav.inc 文件,其中包含以下内容:

<a href="/index.html" rel="external" ><img src="/images/ns.png" alt="Sample Page"/><span class="title" >Demo</span></a>
<a href="/demo.html" rel="external" ><img src="/images/missions.png" alt="Sample Page"/><span class="title" >Demo2</span></a>
<a href="/mobile.html" rel="external" ><img src="/images/ons.png" alt="Sample Page"/><span class="title" >Demo3</span></a>
.
.
.

等等

我想通过 XSL 为每个列表元素获取节点和 @href 的值,并构建一个类似的结构

<li><a href="/index.html" rel="external">Demo</a></li>
.
.

我知道这可以这样做:

<xsl:variable name="vText" select="unparsed-text('nav.inc')"/> 

和类似的东西:

<xsl:variable name="vExtracted" as="xs:token*">
  <xsl:analyze-string select="$vText" regex="" flags="m">
    <xsl:matching-substring>
      <xsl:value-of select="regex-group(1)"/>
    </xsl:matching-substring>
  </xsl:analyze-string>
</xsl:variable>

然后像

<xsl:for-each select="$vExtracted">
  <li><xsl:value-of select="."/></li>
</xsl:for-each >

我不擅长正则表达式。高度赞赏解决此问题的任何帮助。

4

4 回答 4

2

如果您的输入如您所建议的那样有规律,那么您就不需要自己解析它的麻烦,您可以使用 XML 解析器更轻松地完成它。(如果它不像你建议的那样有规律,那么你就不想麻烦了......)。唯一的小障碍是缺少一个封闭的最外层元素,这可以很容易地解决,只需将提供的文本连接到 中<o>...</o>,或者将其作为外部解析实体包含到包装 XML 文档中。

然后,转换变得与单线一样接近:

<xsl:template match="a">
  <li><a href="{@href}" rel="{@rel}"><xsl:value-of select="."/></a></li>
</xsl:template>
于 2013-01-09T09:02:07.687 回答
1

我相信可以公平地说,这个问题对你来说是最好的答案。使用 XML 解析器。

如果您的案例非常简单,可以通过以下方式解决:

<a href="(.*?)" rel="external" ><img src=".*?" alt="Sample Page"/><span class="title" >(.*?)</span></a>

其中,在您的样本上运行搜索和替换,替换$1,$2为我:

/index.html,Demo
/demo.html,Demo2
/mobile.html,Demo3

也许在这种情况下,但是如果要考虑的复杂性比您的示例所表明的要复杂得多,那么正则表达式就无法解析 HTML。

于 2013-01-08T23:22:42.807 回答
1

根据您的 XSLT 2.0 处理器,您可以使用扩展函数来解析unparsed-text(包装在一个元素中以使其格式正确)并且根本不使用正则表达式......

导航公司

<a href="/index.html" rel="external" ><img src="/images/ns.png" alt="Sample Page"/><span class="title" >Demo</span></a>
<a href="/demo.html" rel="external" ><img src="/images/missions.png" alt="Sample Page"/><span class="title" >Demo2</span></a>
<a href="/mobile.html" rel="external" ><img src="/images/ons.png" alt="Sample Page"/><span class="title" >Demo3</span></a>

XSLT 2.0(使用 Saxon-EE 9.4 测试并使用自身作为输入)

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:saxon="http://saxon.sf.net/" extension-element-prefixes="saxon">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:variable name="nav.inc">
        <xsl:text>&lt;doc></xsl:text>
        <xsl:value-of select="unparsed-text('file:///C:/so_test/nav.inc')"/>
        <xsl:text>&lt;/doc></xsl:text>
    </xsl:variable>

    <xsl:template match="/">
        <results>
            <xsl:for-each select="saxon:parse($nav.inc)/*/a">
                <li>
                    <xsl:copy>
                        <xsl:copy-of select="@*"/>
                        <xsl:value-of select="."/>
                    </xsl:copy>
                </li>
            </xsl:for-each>
        </results>
    </xsl:template>

</xsl:stylesheet>

XML 输出

<results>
   <li>
      <a href="/index.html" rel="external">Demo</a>
   </li>
   <li>
      <a href="/demo.html" rel="external">Demo2</a>
   </li>
   <li>
      <a href="/mobile.html" rel="external">Demo3</a>
   </li>
</results>

如果您想进行更复杂的转换,它也可以用作带有单独模板的xsl:apply-templates( )。<xsl:apply-templates select="saxon:parse($nav.inc)/*"/>a

于 2013-01-09T04:38:07.257 回答
0
      <xsl:variable name="vText" select="unparsed-text($source1,$encoding)"/>
          <xsl:variable name="vExtracted" as="element(group)*">
            <xsl:analyze-string select="$vText" regex="&#34;([^&lt;]*)&quot; rel(.*)&gt;([^&lt;]*)&lt;/span&gt;" flags="m">
              <xsl:matching-substring>
                 <group>
                     <x><xsl:value-of select="regex-group(1)"/></x>
                     <y><xsl:value-of select="regex-group(3)"/></y>
                  </group>
              </xsl:matching-substring>
            </xsl:analyze-string>
          </xsl:variable>


          <xsl:for-each select="$vExtracted">
          &lt;li&gt;&lt;a href="<xsl:value-of select="x"/>".*&gt;<xsl:value-of select="y"/>&lt;/a&gt;&lt;/li&gt;
          </xsl:for-each >
于 2013-01-09T01:27:47.047 回答