转换元素中的注释

时间:2015-04-08 11:06:56

标签: xml xslt

我正在尝试转换由包含此文本的元素中的注释分隔的文本。

源XML:

<?xml version="1.0" encoding="utf-8"?>
<DOC>
<TEXT>
<!--SectionLeRubrum-->
<para>R1</para>
<para>R2</para>
<para>...</para>
<!--SectionFaits-->
<para>F1</para>
<para>F2</para>
<para>...</para>
<!--SectionConsiderants-->
<para>C1</para>
<para>C2</para>
<para>...</para>
<!--SectionDispositif-->
<para>D1</para>
<para>D2</para>
<para>...</para>
</TEXT>
</DOC>

我需要转换为:

<?xml version="1.0" encoding="utf-8"?>
<DOC>
<TEXT>
<!--SectionLeRubrum-->
<p>R1</p>
<p>R2</p>
<p>...</p>
<!--SectionFaits-->
<p>F1</p>
<p>F2</p>
<p>...</p>
<!--SectionConsiderants-->
<zone type="considerants">
    <p>C1</p>
    <p>C2</p>
    <p>...</p>
</zone>
<!--SectionDispositif-->
<p>D1</p>
<p>D2</p>
<p>...</p>
</TEXT>
</DOC>

我尝试使用以下说明,但在放入“zone”元素后,我无法删除“C1”,“C2”段落。

<xsl:template match="comment()[contains(.,'SectionConsiderants')]">
    <zone type="considerants">
        <xsl:apply-templates select="//*[preceding-sibling::comment()[.='SectionConsiderants'] and following-sibling::comment()[.='SectionDispositif']][node()]" mode="Zone" />
    </zone>
</xsl:template>

<xsl:template match="comment()">
</xsl:template>

<xsl:template match="*[preceding-sibling::comment()[.='SectionConsiderants'] and following-sibling::comment()[.='SectionDispositif']]" mode="Zone">
    <xsl:apply-templates select="." />
</xsl:template>

错误输出:

<?xml version="1.0" encoding="utf-8"?>
<DOC>
<TEXT>
<!--SectionLeRubrum-->
<p>R1</p>
<p>R2</p>
<p>...</p>
<!--SectionFaits-->
<p>F1</p>
<p>F2</p>
<p>...</p>
<!--SectionConsiderants-->
<zone type="considerants">
    <p>C1</p>
    <p>C2</p>
    <p>...</p>
</zone>
<p>C1</p>
<p>C2</p>
<p>...</p>
<!--SectionDispositif-->
<p>D1</p>
<p>D2</p>
<p>...</p>
</TEXT>
</DOC>

如果我使用补充规则,例如:

<xsl:template match="*[preceding-sibling::comment()='SectionConsiderants' and following-sibling::comment()='SectionDispositif']" />

它会产生以下错误结果:

<?xml version="1.0" encoding="utf-8"?>
<DOC>
<TEXT>
<!--SectionLeRubrum-->
<p>R1</p>
<p>R2</p>
<p>...</p>
<!--SectionFaits-->
<p>F1</p>
<p>F2</p>
<p>...</p>
<!--SectionConsiderants-->
<zone type="considerants" />
<!--SectionDispositif-->
<p>D1</p>
<p>D2</p>
<p>...</p>
</TEXT>
</DOC>

使用“分组”建议的解决方案与“密钥”解决了问题。 感谢。

2 个答案:

答案 0 :(得分:1)

这是一个相当标准的分组问题 - 您需要将每个para元素与其最近的前一个注释相关联,然后处理注释并执行相应的操作每个小组的事情。您可以使用来实现此目的:

<xsl:key name="paraByComment" match="para"
         use="generate-id(preceding-sibling::comment()[1])" />

<xsl:template match="TEXT">
  <xsl:apply-templates select="comment()" />
</xsl:template>

<xsl:template match="comment()[. = 'SectionConsiderants']">
  <xsl:copy-of select="."/>
  <zone type="considerants">
    <xsl:apply-templates select="key('paraByComment', generate-id())" />
  </zone>
</xsl:template>

<xsl:template match="comment()">
  <xsl:copy-of select="."/>
  <xsl:apply-templates select="key('paraByComment', generate-id())" />
</xsl:template>

<xsl:template match="para">
  <p><!-- do whatever you need with the para content --></p>
</xsl:template>

通过该密钥,您可以针对给定的评论检索此评论与下一个评论之间的所有para元素(或此评论以及TEXT的结尾,如果是&# 39;是最后的评论。)

答案 1 :(得分:0)

原则上,您必须在&#34; normal&#34;中排除这些元素。模式由这样的模板:

 <xsl:template match="*[preceding-sibling::comment()='SectionConsiderants' and following-sibling::comment()='SectionDispositif']"/>

但是,这一切只能运作一次:如果您碰巧有多个&#34;区域&#34;,那么结果可能不是您想要的。