1

我一直在寻找这个解决方案,在我放弃之前我想我试着在这里问这个问题。

我有 27 个 XML 文件(在 TEI 中),我有一个 XSLT 样式表 2.0。我编写了一个函数,该函数进入每个 XML 文件并创建一个(一个)新的 html 文件(所有命名人员的列表)。

我的 XML 中的命名人员看起来像这样:

<persName role="addressee">Herr <roleName>Prof. Dr.</roleName>XYY</persName>

或者像这样:

<persName key="linktodatabank">Herr <roleName>Dr.</roleName> Hugo <surname>Müller</surname></persName>

<persName>Herr Heinz</persName>
<persName>Volkm</persName>

虽然它不是一个好的解决方案(我的 XSLT),因为我这样命名每个文件:

<xsl:variable name="persName1" select="document('01_ML.xml')/tei:TEI//tei:persName"/>

var 名称使用 persName2、persName3 等。文档名称使用相同的 02_ML、03_ML 等。我知道有一个计数器会很好,但不知道该怎么做。在我为所有文档命名之后(我对提取地点名称和术语做同样的事情),我创建了一个集合(也不是一个好的解决方案)并像这样尝试它:

 <xsl:variable name="collection2" select="$persName1, $persName2, $persName3, $persName4, $persName5, $persName7, $persName8, $persName9,
                           $persName10, $persName11, $persName12, $persName13, $persName14, $persName15, $persName16, $persName17, $persName18, $persName19, $persName20"></xsl:variable> 
                       <html xmlns="http://www.w3.org/1999/xhtml">
                           <head>
                               <link rel="stylesheet" type="text/css" href="persName.css"/>
                               <title>Personenregister</title></head>
                           <body>
                             <h1 class="title">Personenregister</h1>
                              <ul> 

                                  <xsl:for-each select="$collection2">
                                   <xsl:sort select="string()" order="ascending"/>
                                   <li class="liste"> 
                                       <xsl:variable name="personen" select="normalize-space(string-join(.//text()[not(parent::tei:roleName)], ''))
                                           "></xsl:variable>
                                       <xsl:variable name="personen2" select="normalize-space(string-join(.//text()[not(parent::tei:surname)], ''))
                                           "></xsl:variable>

                                       <xsl:choose>
                                           <xsl:when test="@key">
                                               <xsl:choose>
                                                   <xsl:when test="exists(tei:roleName)"> <a href="{@key}" target="_blank">    <xsl:value-of select="concat($personen, ', ', tei:roleName)"/> </a>
                                                   </xsl:when>
                                                   <xsl:when test="exists(tei:surname)"><a href="{@key}" target="_blank">    <xsl:value-of select="concat($personen2, ', ', tei:surname, ', ', tei:roleName)"/> </a></xsl:when>

                                                   <xsl:otherwise><a href="{@key}" target="_blank"><xsl:value-of select="$personen"/></a></xsl:otherwise>
                                               </xsl:choose>

                                           </xsl:when>
                                           <xsl:otherwise>
                                               <xsl:choose>
                                                   <xsl:when test="exists(tei:roleName)"><xsl:value-of select="concat($personen, ', ', tei:roleName)"/>

                                                   </xsl:when>
                                                   <xsl:otherwise><xsl:value-of select="$personen"/>
                                                      </xsl:otherwise>
                                               </xsl:choose>
                                           </xsl:otherwise>
                                       </xsl:choose>


                                   </li>  

我的 html 列表应按字母顺序命名所有人员,首先是姓氏,然后是角色名,然后是名字。但我不知道如何删除有时出现在我的 persName 中的“Herr”或“Herrn”。你知道怎么做吗?

另一件事是,我想删除所有双重名称。有些名字出现不止一次。

我的新 html 列表应如下所示:

     <li class="liste"><a href="http://d-nb.info/gnd/118738380" target="_blank">Neisser, Albert </a></li>
<li class="liste">Spiethoff, Prof.</li>

我想我把这些代码弄得一团糟。如果有人可以帮助我,那就太好了。

谢谢!

更新:

谢谢您的帮助!看起来好多了!我忘了提到我把这段代码放在我的身体里是因为我使用 xsl:result-document。因此我不能使用 xsl:template。我尝试了不同的版本并找到了这个解决方案:

    <xsl:result-document href="persName.html" method="html" encoding="UTF-16"> 
 <xsl:variable name="collection2"  select="collection('./?select=*_ML.xml')//tei:persName[not(.=preceding-sibling::node())]"> </xsl:variable>
 <xsl:variable name="personen" select="normalize-space(string-join(.//text()[not(parent::tei:roleName)], ''))" />
       <xsl:variable name="personen2" select="normalize-space(string-join(.//text()[not(parent::tei:surname)], ''))" />

  <h1 class="title">Personenregister</h1>
<body>
                              <ul> 

       <xsl:for-each-group select="$collection2" group-by=".">
         <xsl:sort select="string()" order="ascending"/>
          <xsl:sort select="tei:surname" order="ascending"/>
          <xsl:sort select="tei:rolename" order="ascending"/>
          <xsl:sort select="tei:forename" order="ascending"/> 
<xsl:variable name="personen" select="normalize-space(string-join(.//text()[not(parent::tei:roleName)], ''))" />
       <xsl:variable name="personen2" select="normalize-space(string-join(.//text()[not(parent::tei:surname)], ''))" />
       <xsl:choose>
           <xsl:when test="@key">
               <xsl:choose>
                   <xsl:when test="exists(tei:roleName)"><a href="{@key}" target="_blank"><xsl:value-of select="concat($personen, ', ', tei:roleName)"                    /></a></xsl:when>
                   <xsl:when test="exists(tei:surname)" ><a href="{@key}" target="_blank"><xsl:value-of select="concat($personen2, ', ', tei:surname, ', ', tei:roleName)"/></a></xsl:when>
                   <xsl:otherwise><a href="{@key}" target="_blank"><xsl:value-of select="$personen"/></a></xsl:otherwise>
               </xsl:choose>
           </xsl:when>
           <xsl:otherwise>
               <xsl:choose>
                   <xsl:when test="exists(tei:roleName)"><xsl:value-of select="concat($personen, ', ', tei:roleName)"/></xsl:when>
                   <xsl:otherwise><xsl:value-of select="$personen"/></xsl:otherwise>
               </xsl:choose>
           </xsl:otherwise>
       </xsl:choose>

“Herr”和“Herrn”(先生)的东西:我只想有姓氏,名字和头衔,但没有先生或夫人(Herr)。所以我想删除“Herr”,只要它出现在我的 persName 中

4

1 回答 1

1

这是您的 XSLT 的修订版本。它几乎是一个精确的副本,但有一些结构修改:

<xsl:stylesheet version="2.0" xmlns="http://www.w3.org/1999/xhtml" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:tei="http://uri.com/goes/here">
    <xsl:template match="/">
        <html>
           <head>
                <link rel="stylesheet" type="text/css" href="persName.css"/>
                <title>Personenregister</title>
            </head>
            <body>
                <h1 class="title">Personenregister</h1>
                <ul> 
                    <xsl:apply-templates select="collection('./?select=*_ML.xml')//tei:persName[not(.=preceding-sibling::node())]">
                        <xsl:sort select="string()" order="ascending"/>
                    </xsl:apply-templates>
                </ul>
            </body>
        </html>
    </xsl:template>

    <xsl:template match="tei:persName">
        <xsl:message>
            <xsl:text>in template</xsl:text>
        </xsl:message>
        <li class="liste"> 
           <xsl:variable name="personen" select="normalize-space(string-join(.//text()[not(parent::tei:roleName)], ''))" />
           <xsl:variable name="personen2" select="normalize-space(string-join(.//text()[not(parent::tei:surname)], ''))" />
           <xsl:choose>
               <xsl:when test="@key">
                   <xsl:choose>
                       <xsl:when test="exists(tei:roleName)"><a href="{@key}" target="_blank"><xsl:value-of select="concat($personen, ', ', tei:roleName)"                    /></a></xsl:when>
                       <xsl:when test="exists(tei:surname)" ><a href="{@key}" target="_blank"><xsl:value-of select="concat($personen2, ', ', tei:surname, ', ', tei:roleName)"/></a></xsl:when>
                       <xsl:otherwise><a href="{@key}" target="_blank"><xsl:value-of select="$personen"/></a></xsl:otherwise>
                   </xsl:choose>
               </xsl:when>
               <xsl:otherwise>
                   <xsl:choose>
                       <xsl:when test="exists(tei:roleName)"><xsl:value-of select="concat($personen, ', ', tei:roleName)"/></xsl:when>
                       <xsl:otherwise><xsl:value-of select="$personen"/></xsl:otherwise>
                   </xsl:choose>
               </xsl:otherwise>
           </xsl:choose>
        </li>
    </xsl:template>
</xsl:stylesheet>

最大的变化发生在这里:

<xsl:apply-templates select="collection('./?select=*_ML.xml')//tei:persName[not(.=preceding-sibling::node())]">
    <xsl:sort select="string()" order="ascending"/>
</xsl:apply-templates>

这是选择所有组件文件的更好方法。XPath 函数collection('./?select=*_ML.xml')将选择工作路径中匹配的所有文件*_ML.xml,并将该文件集转换为一组节点。然后,我们选择所有persName元素的集合。

然后,为了只选择不同的persName元素,我们应用一个谓词:not(.=preceding-sibling::node()). 该谓词表示忽略与我们已经处理过的节点具有相同内容的所有节点。这要求节点完全相等,因此如果这太严格,您可以修改谓词以满足您的需要。

在此之后,我们按字母顺序对节点进行排序,升序。您可以在apply-templates指令中执行此操作。您还可以包含多个sort指令以对多个字段进行排序(当然,您需要将以下 select 语句替换为实际语句):

<xsl:sort select="surname" order="ascending"/>
<xsl:sort select="rolename" order="ascending"/>
<xsl:sort select="forename" order="ascending"/>

我想这就是你所要求的一切......嗯......嗯,就是这样:

但我不知道如何删除有时出现在我的 persName 中的“Herr”或“Herrn”。你知道怎么做吗?

给我们看一个例子,因为我不能 100% 确定你的意思。什么时候有时会出现不应该的情况?

PS这是我的测试的示例输出,以表明它正在工作:

**01_ML.xml:**
<persName xmlns="http://uri.com/goes/here" role="addressee">Herr <roleName>Prof. Dr.</roleName>XYY</persName>

**02_ML.xml:**
<TEI xmlns="http://uri.com/goes/here">
    <persName key="linktodatabank">Herr <roleName>Dr.</roleName> Hugo <surname>Muller</surname></persName>

    <persName>Herr Heinz</persName>
    <persName>Herr Heinz</persName>
    <persName>Herr Heinz</persName>
    <persName>Herr Heinz</persName>
    <persName>Herr Heinz</persName>
    <persName>Herr Heinz</persName>
    <persName>Herr Heinz</persName>
    <persName>Herr Heinz</persName>
    <persName>Volkm</persName>
</TEI>

<?xml version="1.0" encoding="UTF-8"?><html xmlns="http://www.w3.org/1999/xhtml" xmlns:tei="http://uri.com/goes/here">
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
      <link rel="stylesheet" type="text/css" href="persName.css" />
      <title>Personenregister</title>
   </head>
   <body>
      <h1 class="title">Personenregister</h1>
      <ul>
         <li class="liste"><a href="linktodatabank" target="_blank">Herr Hugo Muller, Dr.</a></li>
         <li class="liste">Herr Heinz</li>
         <li class="liste">Herr XYY, Prof. Dr.</li>
         <li class="liste">Volkm</li>
      </ul>
   </body>
</html>
于 2013-10-18T16:10:41.060 回答