【问题标题】:Regex on unparsed text未解析文本的正则表达式
【发布时间】:2013-01-08 23:11:50
【问题描述】:

我有一个包含以下内容的 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 >

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

【问题讨论】:

  • 为此使用 RegEx 没有意义。请参阅 Michael Kay 的简单而优雅的答案。借助 XSLT 3.0 处理器,您可以使用新的标准 XPath 3.0 函数 parse-xml() 在转换内部执行解析。

标签: xml regex xslt xml-parsing xslt-2.0


【解决方案1】:

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

然后转换变得尽可能接近单线:

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

【讨论】:

    【解决方案2】:

    我相信可以公平地说,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。

    【讨论】:

      【解决方案3】:

      根据您的 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 (&lt;xsl:apply-templates select="saxon:parse($nav.inc)/*"/&gt;) 和单独的 a 模板。

      【讨论】:

        【解决方案4】:
              <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 >
        

        【讨论】:

          猜你喜欢
          • 2012-05-18
          • 1970-01-01
          • 2016-04-27
          • 1970-01-01
          • 2015-10-10
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多