我有一个简单的xml文本和一个小人物。我想找到所有人'在文中提到并使用人物学中的信息标记它们。 我的文字看起来像这样:
<text>
<div>
<p>Mohandas Ghandi was an Indian lawyer, born in 1869.</p>
<p>Albert Einstein was a German physicist, born in 1879.</p>
<p>Helen Keller was an American author, born in 1880.</p>
<p>Joan Baez is an American singer/songwriter, born in 1941.</p>
</div>
</text>
我的人物外观如下:
<people>
<person id="ghandi">
<name>Mohandas Ghandi</name>
<birthPlace>Porbandar, India</birthPlace>
</person>
<person id="einstein">
<name>Albert Einstein</name>
<birthPlace>Ulm, Germany</birthPlace>
</person>
<person id="keller">
<name>Helen Keller</name>
<birthPlace>Tuscumbia, USA</birthPlace>
</person>
</people>
到目前为止,我有这个xslt(2.0):
<xsl:variable name="personography" select="doc('people.xml')"/>
<xsl:variable name="pName" select="$personography//person[1]/name"/>
<xsl:variable name="pId" select="$personography//person[1]/@id"/>
<xsl:template match="*">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template name="encNames" match="text()">
<xsl:analyze-string select="." regex="{$pName}">
<xsl:matching-substring>
<persName corresp="{concat('people.xml#',$pId)}">
<xsl:value-of select="."/>
</persName>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:copy-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
我得到了回复:
<text>
<div>
<p><persName corresp="people.xml#ghandi">Mohandas Ghandi</persName> was an Indian lawyer, born in 1869.</p>
<p>Albert Einstein was a German physicist, born in 1879.</p>
<p>Helen Keller was an American author, born in 1880.</p>
<p>Joan Baez is an American singer/songwriter, born in 1941.</p>
</div>
</text>
所以,我的问题是,如何在我的文本中标记其余的人?我假设它需要一个使用跟随兄弟的功能,但我还没有比这更进一步。我错过了什么?我至少走在正确的轨道上吗? 感谢。
答案 0 :(得分:1)
我要做的是更改pName
以返回一系列名称而不是第一个人的名字。然后,我将使用该序列构建一个新的正则表达式。
示例...
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:preserve-space elements="p"/>
<xsl:variable name="personography" select="doc('people.xml')"/>
<xsl:variable name="pName" select="$personography/*/person/name"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()" priority="1">
<xsl:analyze-string select="." regex="({string-join($pName,'|')})">
<xsl:matching-substring>
<persName corresp="{concat('people.xml#',$personography/*/person[name=current()]/@id)}">
<xsl:value-of select="."/>
</persName>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:copy-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:0)
它有点冗长,可能会被优化或重构,但有效。
此模板将遍历每个人并应用analyze-string。结果位于名为$person-matches
的变量中,每个人都有一个<match>
。
如果匹配的内容包含<persName>
,请使用该匹配项。否则,请使用模板中匹配的原始文本。
<xsl:template match="text()">
<xsl:variable name="txt" select="."/>
<xsl:variable name="person-matches">
<xsl:for-each select="$personography/person">
<xsl:variable name="person" select="."/>
<match>
<xsl:analyze-string select="$txt" regex="({$person/name})">
<xsl:matching-substring>
<persName corresp="{concat('people.xml#',$person/@id)}">
<xsl:value-of select="regex-group(1)"/>
</persName>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</match>
</xsl:for-each>
</xsl:variable>
<xsl:choose>
<xsl:when test="$person-matches/match[persName]">
<xsl:sequence select="$person-matches/match[persName]/node()"/>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>