2016-01-18 26 views
0

我正在嘗試格式化xml並將一些字段複製到較低級別,因此我在將密鑰導入到Access時有密鑰。 試圖將字段號添加到ActivityLog的部分。 就像我爲標識符做的那樣,但我沒有找到一種方法來處理數字 我無法調整xml,因爲這是應用程序的導出。使用XSLT轉換xml以在較低級別添加密鑰

<?xml version="1.0" encoding="windows-1252"?> 
      <NotificationReport xmlns="http://www.xyyyxx.com/extraction/notification"> 
       <NotificationElement> 
        <Identifier>13689</Identifier> 
        <NotificationElementAcceptance> 
        <NotificationElement> 
         <VersionNumber> 
         <Number>2</Number> 
         </VersionNumber> 
         <NotificationElementAcceptance> 
         <ActivityLogs> 
          <ActivityLog> 
          <ActivityLogId>NE-720177</ActivityLogId> 
          <ActivityStartDateTime>2015-11-03T17:09:30.475</ActivityStartDateTime> 
          <CreationDateTime>2015-11-03T17:09:30.475</CreationDateTime> 
          <ActivityIndex>1</ActivityIndex> 
          <CompleteProcessStatus>Change notification element</CompleteProcessStatus> 
          </ActivityLog> 
         </ActivityLogs> 
         </NotificationElementAcceptance> 
        </NotificationElement> 
        </NotificationElementAcceptance> 
      </NotificationElement> 
      </NotificationReport> 

- >我已創建了現在,直到XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" > 
    <xsl:output indent="yes"/> 
    <xsl:strip-space elements="*"/> 

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

    <xsl:template match="ActivityLog"> 
     <ActivityLog> 
      <Identifier><xsl:value-of select="../../../../../Identifier"/></Identifier> 
      <xsl:apply-templates select="@*|node()"/> 
     </ActivityLog> 
    </xsl:template> 

預期結果

<?xml version="1.0" encoding="utf-8"?> 
     <NotificationReport xmlns="http://www.xyyyxx.com/extraction/notification"> 
      <NotificationElement> 
       <Identifier>13689</Identifier> 
       <NotificationElementAcceptance> 
       <NotificationElement> 
        <VersionNumber> 
         <Number>2</Number> 
        </VersionNumber> 
        <NotificationElementAcceptance> 
         <ActivityLogs> 
          <ActivityLog> 
          <Identifier>13689</Identifier> 
          <VersionNumber>2</VersionNumber> 
          <ActivityLogId>NE-720177</ActivityLogId> 
          <ActivityStartDateTime>2015-11-03T17:09:30.475</ActivityStartDateTime> 
          <CreationDateTime>2015-11-03T17:09:30.475</CreationDateTime> 
          <ActivityIndex>1</ActivityIndex> 
          <CompleteProcessStatus>Change notification element</CompleteProcessStatus> 
          </ActivityLog> 
         </ActivityLogs> 
        </NotificationElementAcceptance> 
       </NotificationElement> 
       </NotificationElementAcceptance> 
      </NotificationElement> 
     </NotificationReport> 
+0

您能否提供您的示例所需的輸出?這會有很大的幫助。 – hielsnoppe

+0

預期的結果被添加到問題中(沒有得到makup正確) –

回答

1

這是由於命名空間。你已經在你的XML

<NotificationReport xmlns="http://www.xyyyxx.com/extraction/notification"> 

聲明默認命名空間這意味着元素,所有後代(除非沒有其他命名空間聲明覆蓋)是空間的一部分。特定名稱空間中的元素與位於不同名稱空間中的元素不同,或者沒有名稱空間,即使元素具有相同的名稱。

在您的XSLT中,根本沒有對命名空間的引用。因此,當您執行<xsl:template match="ActivityLog">時,它會嘗試匹配名爲ActivityLog的元素,該元素不在名稱空間中,對於您的XML而言並非如此。

解決方案是在您的XSLT中聲明命名空間,並將其包含在模板匹配中。

試試這個XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:n="http://www.xyyyxx.com/extraction/notification"> 
    <xsl:output indent="yes"/> 
    <xsl:strip-space elements="*"/> 

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

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

注意使用命名空間前綴n的是任意的。它所連接的名稱空間URI必須與輸入XML匹配。

+0

命名空間被錯誤地複製(我改變了它,因爲url中的名稱(公司明智) –

+0

當您發佈信息時更改敏感細節一個問題,你只需要確保你在XSLT中聲明瞭命名空間,使用與XML中指定的相同的URI。 –

+0

你可以在http://www.xml.com/上閱讀XML和XSLT中的命名空間。 pub/a/1999/01/namespaces.html和http://www.xml.com/pub/a/2001/04/04/trxml/ –

0

我找到了解決辦法()

- >這樣我就可以上去,之後在其他節點再次下井。 :)在Xml Noob。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output indent="yes"/> 
<xsl:strip-space elements="*"/> 

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

<xsl:template match="heal:ActivityLog"> 
    <heal:ActivityLog> 
     <heal:Identifier><xsl:value-of select="../../../not:Identifier"/></heal:Identifier> 
     <heal:VersionNumber><xsl:value-of select="../../not:NotificationElement/not:VersionNumber"/></heal:VersionNumber> 
     <xsl:apply-templates select="@*|node()"/> 
    </heal:ActivityLog> 
</xsl:template> 

+0

'heal'和'not'命名空間來自哪裏? – hielsnoppe

+1

此樣式表不正確,因爲它是格式不正確的XML。正如前面的評論者所指出的那樣,存在未聲明的前綴。 –

0

Tim是正確的關於命名空間(見his answer的解釋)。以下轉換實際上將給定的輸入(如問題中發佈的)轉換爲預期的輸出:

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns="http://www.xyyyxx.com/extraction/notification" 
    xmlns:n="http://www.xyyyxx.com/extraction/notification"> 

    <xsl:output indent="yes"/> 
    <xsl:strip-space elements="*"/> 

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

    <xsl:template match="n:ActivityLog"> 
     <xsl:copy> 
      <xsl:copy-of select="../../../../../n:Identifier"/> 

      <VersionNumber> 
       <xsl:value-of select="../../../n:VersionNumber/n:Number"/> 
      </VersionNumber> 

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

謝謝 - >確實工作完美 –

+0

您可能想考慮接受其中一個答案。蒂姆的,因爲它是第一個正確或者我的名字空間,你認爲合適。這將使你和所接受的答案的作者獲得一些聲譽。歡迎來到StackOverflow! – hielsnoppe