使用Xpath按类查找元素

时间:2018-01-31 05:00:18

标签: html xslt xpath

我试图通过分离特定类的元素来格式化和过滤html到所需的格式。我的html输入如下:

<body style="background-color:#FFFFFF;margin:0px;padding:0px">
<div class="pdf_page" id="pdf_page1" style="width:707px;height:1024px">
<span class="pdf_text pdf_text0" style="top:50px;left:688px">1</span>
<span class="pdf_text pdf_text1" style="top:119px;left:96px">Healthcare 
Hospitals</span>
<span class="pdf_text pdf_text4" style="top:190px;left:96px">PUBLIC 
HOSPITALS/MEDICAL CLINICS</span>
<span class="pdf_text pdf_text5" style="top:207px;left:96px">Alexandra 
Hospital</span>
<span class="pdf_text pdf_text5" style="top:224px;left:96px">Admiralty 
Medical Centre</span>
<span class="pdf_text pdf_text5" style="top:241px;left:96px">Changi General 
Hospital</span>
<span class="pdf_text pdf_text4" style="top:460px;left:96px">PRIVATE 
HOSPITALS/MEDICAL CLINICS</span>
<span class="pdf_text pdf_text5" style="top:477px;left:96px">Farrer Park 
Hospital</span>
<span class="pdf_text pdf_text5" style="top:494px;left:96px">Fortis Surgical 
Hospital</span>
<span class="pdf_text pdf_text5" style="top:511px;left:96px">Gleneagles 
Hospital</span>
<span class="pdf_text pdf_text4" style="top:662px;left:96px">DAY SURGERY 
CENTRES</span>
<span class="pdf_text pdf_text5" style="top:679px;left:96px">A Clinic For 
Women</span>
<span class="pdf_text pdf_text5" style="top:696px;left:96px">A Company For 
Women</span>
</div>
...

我在下面写了一个片段来格式化它,以便我可以将所有的Span与类分开为&#39; pdf_text pdf_text4&#39;

<xsl:template match="/">
  <vce>
<xsl:apply-templates value="body" />
   </vce>
</xsl:template>
<xsl:template match="div">
  <document>
    <content name="header">
      <xsl:value-of select="(//span[contains(@class, 'pdf_text pdf_text4')])" />
    </content>
    <content name="data">
      <xsl:value-of select="." />
</content>
  </document>
</xsl:template>

但有了这个,我得到的输出如下:

<vce>
<document>
<content name="header">PUBLIC HOSPITALS/MEDICAL CLINICS</content>
<content name="data">
1 Healthcare List of M...
</content>
</document>
<document>
<content name="header">PUBLIC HOSPITALS/MEDICAL CLINICS</content>
<content name="data">
1 Healthcare List of M...
</content>
</document>

如果您在上面看到,&#34;公共医院/医疗诊所&#34;一次又一次地重复,而不是选择具有匹配类的下一个跨度内容。

我做错了什么?

2 个答案:

答案 0 :(得分:0)

使用

<xsl:value-of select="(descendant-or-self::span[contains(@class, 'pdf_text pdf_text4')])" />

而不是

<xsl:value-of select="(//span[contains(@class, 'pdf_text pdf_text4')])" />

请参阅http://xsltransform.net/pNvs5vM

处的转化

答案 1 :(得分:0)

我根据模板递归在版本 1.0 中准备了一个脚本。

主模板(匹配&#34; /&#34;)调用&#34;正常&#34;模板只处理 类{em> ... text4 。{/ p>的span元素

这&#34;正常&#34; span 的模板首先处理自己的元素 (创建标题),然后开始处理以下span元素 (使用类 ... text5 ),通过在 cell 模式下调用另一个模板, 处理下一个兄弟姐妹。 由于递归,这个处理继续进行,而有下一个兄弟 与班级 ... text5

&#34;开始&#34;递归呼叫(来自&#34;正常&#34;模板)被&#34;封闭&#34;在 <content name="data">元素。 有关详细信息,请参阅下文。

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
  <xsl:strip-space elements="*"/>

  <xsl:template match="/">
    <vce><document>
      <xsl:apply-templates select="body/div/span[contains(@class, 'text4')]"/>
    </document></vce>
  </xsl:template>

  <xsl:template match="span">
    <!-- First process the current span (text4) -->
    <content name="header">
      <xsl:value-of select="." />
    </content>
    <!-- Then, recursively, text5, starting from the next -->
    <content name="data">
      <xsl:apply-templates select="following-sibling::*[1]" mode="cell"/>
    </content>
  </xsl:template>

  <!-- Recursive processing of text5 spans -->
  <xsl:template match="span" mode="cell">
    <!-- Process the current span -->
    <xsl:value-of select="."/>
    <!-- Find the next span (if any) -->
    <xsl:variable name="nextItem" select="following-sibling::*[1][self::span]
      [contains(@class, 'text5')]"/>
    <!-- Next span found -->
    <xsl:if test="$nextItem">
      <!-- Separator -->
      <xsl:text>, </xsl:text>
      <!-- Process the next span -->
      <xsl:apply-templates select="$nextItem" mode="cell"/>
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>