我有一个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 >
我不擅长正则表达式。任何帮助解决这个问题的人都非常感谢。
答案 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><doc></xsl:text>
<xsl:value-of select="unparsed-text('file:///C:/so_test/nav.inc')"/>
<xsl:text></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=""([^<]*)" rel(.*)>([^<]*)</span>" 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">
<li><a href="<xsl:value-of select="x"/>".*><xsl:value-of select="y"/></a></li>
</xsl:for-each >