扫描xml文件内容并创建新元素

时间:2011-12-01 15:55:18

标签: xslt

我有一个xml文件

<xml>
 <head>
 <title>Test</title>
  </head>
 <body>
     <para>
     This is a body text meta data 1234, this is a external link R12345.  This is a test para.
     </para>
   </body>
 </xml>

我需要一个脚本,它将扫描 body / para 文本的内容,以查找“元数据”,“外部链接”,其中包含这些单词后面的数字并将其转换为链接在头部。

<xml>
 <head>
 <title>Test</title>
 <link name="meta data" id="1234"/>
 <link name="external link" id="R1234"/>
  </head>
 <body>
     <para>
     This is a body text meta data 1234, this is a external link R12345. This is a test para. 
     </para>
   </body>
 </xml>

我使用c#programe完成了它,但是想要使用xslt 1.0来完成它,因为我在同一个文件上运行的其他转换很少,所以想在xslt中这样做。

1 个答案:

答案 0 :(得分:1)

您的问题存在轻微的不一致,因为您说您要查找代码后面的数字,但在您的示例中,外部的数字是 R1234 显然包含一封信!

然而,我提出了以下模板,可用于扫描&#39;为您的标签

<xsl:template name="sweeper">
  <xsl:param name="text"/>
  <xsl:param name="tag"/>

  <xsl:variable name="search" select="normalize-space(concat(substring-after($text, $tag), '.'))"/>
  <xsl:variable name="delimiter" select="substring(translate($search, 'R1234567890', ''), 1, 1)"/>
  <xsl:variable name="match" select="substring-before($search, $delimiter)"/>
  <xsl:if test="$match != ''">
     <link name="{$tag}" id="{$match}"/>
  </xsl:if>
</xsl:template>

文字是要搜索的文字,而标记是要对其进行排序的标记。)

模板的作用首先是在&#39;之后获取文字。您正在搜索的标签。然后它会删除此字符串中的所有数字,以及R以满足您的要求(如果其他字母有效,请在此处添加)。然后它获取在此截断文本的第一个字符之前出现的文本,该文本应该是您想要的数字。

这是完整的XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes"/>

   <xsl:template match="head">
      <xsl:copy>
         <xsl:apply-templates select="@*|node()"/>
         <xsl:apply-templates select="//para" mode="sweep"/>
      </xsl:copy>
   </xsl:template>

   <xsl:template match="para" mode="sweep">
      <xsl:call-template name="sweeper">
         <xsl:with-param name="text" select="."/>
         <xsl:with-param name="tag" select="'meta data'"/>
      </xsl:call-template>
      <xsl:call-template name="sweeper">
         <xsl:with-param name="text" select="."/>
         <xsl:with-param name="tag" select="'external link'"/>
      </xsl:call-template>
   </xsl:template>

   <xsl:template name="sweeper">
      <xsl:param name="text"/>
      <xsl:param name="tag"/>

      <xsl:variable name="search" select="normalize-space(concat(substring-after($text, $tag), '.'))"/>
      <xsl:variable name="delimiter" select="substring(translate($search, 'R1234567890', ''), 1, 1)"/>
      <xsl:variable name="match" select="substring-before($search, $delimiter)"/>
      <xsl:if test="$match != ''">
         <link name="{$tag}" id="{$match}"/>
      </xsl:if>
   </xsl:template>

   <xsl:template match="@*|node()">
      <xsl:copy>
         <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
   </xsl:template>
</xsl:stylesheet>

当应用于您的输入XML时,输出如下:

<xml>
<head>
<title>Test</title>
<link name="meta data" id="1234" />
<link name="external link" id="R12345" />
</head>
<body>
<para> 
     This is a body text meta data 1234, this is a external link R12345.  This is a test para. 
     </para>
</body>
</xml>