正则表达未解析的文本

时间:2013-01-08 23:11:51

标签: xml regex xslt xml-parsing xslt-2.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 个答案:

答案 0 :(得分:2)

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

然后变换就像接近单行一样接近:

<xsl:template match="a">
  <li><a href="{@href}" rel="{@rel}"><xsl:value-of select="."/></a></li>
</xsl:template>

答案 1 :(得分:1)

我认为可以公平地说,this question对你来说是最好的答案。使用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。

答案 2 :(得分:1)

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

<强> 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>

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的单独模板。

答案 3 :(得分: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 >
相关问题