2011-12-01 55 views
1

我有一个XML文件扫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> 

我需要一个脚本这将席卷体/对文本查找“元数据”的内容,“外部链接“与这些单词后面的数字,并将它们转换为链接到头部。

<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

有一个在你的问题中略低不一致,因为你说你想找到下面的标签的数量,但在你的榜样,为您外部数为R1234这显然含有字母!

不过,我想出了下面的模板可用于“扫”为您的标记

<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> 

(其中文本是搜索文本,标签是标记)

该模板所做的工作首先是在正在搜索的标签后面获取文本。然后它从该字符串中删除所有数字,以及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> 
+0

感谢蒂姆,它完美地工作。只有一件事我们可以循环关键词的所有发生。如果我们在xml中有多个“元数据”,它只是选择第一个而忽略其他元素。 – atif

+0

巧妙地使用'translate'和'substring'来找到分隔符。此外,处理行尾边缘情况的奖励点。 –

+0

@atif您可以尝试递归调用** sweeper **模板,并将** search **文本作为** text **参数传入。 –