2012-09-06 126 views
1

我有一個XSL需要過濾掉XML中找到的特定數據。用****替換XML中的所有字符串實例

某處在我的XML會有一個節點,如:

<id root="2.16.840.1.113883.3.51.1.1.6.1" extension="9494949494949" />

的XSL我有以下刪除擴展節點,並增加了nullFlavor = 「MSK」到節點。

我現在需要做的是從擴展節點獲取值,然後在整個XML文檔中搜索該值,並將其替換爲* *。

但我不知道如何採取擴展屬性,並找到在XML該值的所有實例(他們可以在文本中的屬性被安葬),並把它們變成* *(4 *)。

下面的例子只是一個例子。我無法對XSL進行硬編碼以查看特定節點,因此需要查看xml中的所有文本/屬性文本(原因在於這裏將應用5個以上不同版本的XML)。

我需要在節點中找到擴展,然後從剩餘的XML中替換(真的刪除)該值。我正在尋找適合所有消息的1解決方案,因此全局搜索 - >擴展值的擦除。

實施例:

 <identifiedPerson classCode="IDENT"> 
       <id root="2.16.840.1.113883.3.51.1.1.6.1" extension="9494949494949" displayable="true" /> 
       <addr use="PHYS"> 
        <city>KAMLOOPS</city> 
        <country>CA</country> 
        <postalCode>V1B3C1</postalCode> 
        <state>BC</state> 
        <streetAddressLine>1A</streetAddressLine> 
        <streetAddressLine>2A</streetAddressLine> 
        <streetAddressLine>9494949494949</streetAddressLine> 
        <streetAddressLine>4A</streetAddressLine>       
       </addr> 
       <note text="9494949494949 should be stars"/> 

應(以下XSLT已經掩蓋了延伸在與匹配的OID節點)。

  <identifiedPerson classCode="IDENT"> 
       <id root="2.16.840.1.113883.3.51.1.1.6.1" nullFlavor="MSK" displayable="true" /> 
       <addr use="PHYS"> 
        <city>KAMLOOPS</city> 
        <country>CA</country> 
        <postalCode>V1B3C1</postalCode> 
        <state>BC</state> 
        <streetAddressLine>1A</streetAddressLine> 
        <streetAddressLine>2A</streetAddressLine> 
        <streetAddressLine>****</streetAddressLine> 
        <streetAddressLine>4A</streetAddressLine>       
       </addr> 
       <note text="**** should be stars"/> 

任何幫助,將不勝感激。

我能夠使用XSL 2.0

我目前XSL.IT工作正常。它匹配根目錄爲'2.16.840.1.113883.3.51.1.1.6.1'的任何標籤,殺死所有屬性並添加一個nullFlavor =「MSK」。但是,這不會搜索同一個#的整個XML。

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

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

    <xsl:template match="@*"> 
     <xsl:choose> 
     <xsl:when test="../@root = '2.16.840.1.113883.3.51.1.1.6.1'"> 
      <xsl:copy-of select=".[contains($attrToKeep, name())]" />  
      <xsl:attribute name="nullFlavor">MSK</xsl:attribute> 
      <!-- Need some way to use the value found in this node and hide the extension --> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:copy-of select="." /> 
     </xsl:otherwise> 
     </xsl:choose> 
    </xsl:template> 
</xsl:stylesheet> 

任何幫助,將不勝感激。

感謝,

回答

1

嘗試使用變量來保存要替換的文本的值。就像這樣:

<xsl:variable 
    name="rootVar" 
    select="//*[@root = '2.16.840.1.113883.3.51.1.1.6.1']/@extension" /> 

然後你就應該能夠使用replace功能來取代它們。

<xsl:template match="'//@*' | text()"> 
    <xsl:sequence select="replace(., $rootVar, '****')"/> 
</xsl:template> 
+0

在文本中查找和替換時可以正常工作。屬性會發生什麼? –

+0

將模板更改爲匹配// @ * |文本(),它很好用! –

+0

嗯,似乎我把match =「// @ * | text()」中的更新刪除了所有的屬性,並將這些值放入實際的xml節點中。 –

0

的XSLT 2.0樣式表

<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    version="2.0"> 

    <xsl:param name="replacement" select="'****'"/> 

    <xsl:param name="new" select="'MKS'"/> 

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

    <xsl:template match="identifiedPerson"> 
    <xsl:copy> 
     <xsl:apply-templates select="@* , node()"> 
     <xsl:with-param name="to-be-replaced" select="id/@extension" tunnel="yes"/> 
     </xsl:apply-templates> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="identifiedPerson//text()"> 
    <xsl:param name="to-be-replaced" tunnel="yes"/> 
    <xsl:sequence select="replace(., $to-be-replaced, $replacement)"/> 
    </xsl:template> 

    <xsl:template match="identifiedPerson//@*"> 
    <xsl:param name="to-be-replaced" tunnel="yes"/> 
    <xsl:attribute name="{name()}" namespace="{namespace-uri()}" select="replace(., $to-be-replaced, $replacement)"/> 
    </xsl:template> 

    <xsl:template match="identifiedPerson/id"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*"/> 
     <xsl:attribute name="nullFlavor" select="$new"/> 
     <xsl:apply-templates/> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="identifiedPerson/id/@extension"/> 

</xsl:stylesheet> 

轉換

<identifiedPerson classCode="IDENT"> 
     <id root="2.16.840.1.113883.3.51.1.1.6.1" extension="9494949494949" displayable="true" /> 
     <addr use="PHYS"> 
      <city>KAMLOOPS</city> 
      <country>CA</country> 
      <postalCode>V1B3C1</postalCode> 
      <state>BC</state> 
      <streetAddressLine>1A</streetAddressLine> 
      <streetAddressLine>2A</streetAddressLine> 
      <streetAddressLine>9494949494949</streetAddressLine> 
      <streetAddressLine>4A</streetAddressLine>       
     </addr> 
     <note text="9494949494949 should be stars"/> 
</identifiedPerson> 

與撒克遜9.4到

<?xml version="1.0" encoding="UTF-8"?><identifiedPerson classCode="IDENT"> 
       <id root="2.16.840.1.113883.3.51.1.1.6.1" displayable="true" nullFlavor="MKS"/> 
       <addr use="PHYS"> 
        <city>KAMLOOPS</city> 
        <country>CA</country> 
        <postalCode>V1B3C1</postalCode> 
        <state>BC</state> 
        <streetAddressLine>1A</streetAddressLine> 
        <streetAddressLine>2A</streetAddressLine> 
        <streetAddressLine>****</streetAddressLine> 
        <streetAddressLine>4A</streetAddressLine> 
       </addr> 
       <note text="**** should be stars"/> 
     </identifiedPerson> 

所以對於樣本就解決了這個問題,我認爲。我不確定是否可以有更多關於該示例的上下文,以及是否要更改identifiedPerson元素以外的值,或者不想更改它們(上面的樣式表)。如果還需要更改其他元素,請考慮發佈較長的輸入和想要的結果樣本來說明並說明確定要替換值的節點的位置。

基於您的評論[編輯] 我適應的樣式,它現在有一個參數的ID傳遞(如2.16.840.1.113883.3.51.1.1.6.1),然後查找任何名稱與一個root屬性的元素具有的ID通過值,並替換在文檔中找到的所有屬性和所有文本節點中找到的extension屬性值。此外,nullFlavor屬性被添加到具有該id的元素,並且其extension屬性被移除。

<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    version="2.0"> 

    <xsl:param name="root-id" select="'2.16.840.1.113883.3.51.1.1.6.1'"/> 
    <xsl:variable name="to-be-replaced" select="//*[@root = $root-id]/@extension"/> 

    <xsl:param name="replacement" select="'****'"/> 

    <xsl:param name="new" select="'MKS'"/> 

    <xsl:template match="comment() | processing-instruction()"> 
    <xsl:copy/> 
    </xsl:template> 

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

    <xsl:template match="text()"> 
    <xsl:sequence select="replace(., $to-be-replaced, $replacement)"/> 
    </xsl:template> 

    <xsl:template match="@*"> 
    <xsl:attribute name="{name()}" namespace="{namespace-uri()}" select="replace(., $to-be-replaced, $replacement)"/> 
    </xsl:template> 

    <xsl:template match="*[@root = $root-id]"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*"/> 
     <xsl:attribute name="nullFlavor" select="$new"/> 
     <xsl:apply-templates/> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="*[@root = $root-id]/@extension"/> 

</xsl:stylesheet> 
+0

感謝您的意見。文檔格式不是固定的,所以我不能硬編碼XSL來搜索特定的節點。它需要檢查所有的OID(2.16.840.1.113883.3.51.1.1.6.1)中找到的正確值。我會更新quesiton –

相關問題