2011-12-01 63 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 **參數傳入。 –