2012-10-26 89 views
1

我有一個XML文件轉換爲XML使用XSLT的問題。 我似乎可以得到的第一個節點,但母雞我不能讓節點命名,其屬性和價值的attribues,並在某些情況下,節點有一個節點名爲至極具有屬性和值,我需要: 下面是一個例子文件(編輯:空格添加legiblity):的XML xml的使用XSLT與節點具有相同名稱的

<?xml version='1.0' encoding='UTF-8'?> 
<arb:result xmlns:arb="urn::codeservice"> 
<arb:document 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="urn::codeservice prod_code.xsd"> 
    <header>Produced by CodeRows 4.2</header> 
    <body> 
    <termsystem id="1" begindate="1970-01-01T00:00:01" 
     expirationdate="2099-12-31T23:59:59" 
     lastmodifieddate="2012-10-05T09:52:02.35522" 
     lastmodifiedby="Admin"> 
    <attribute type="longname" datatype="ST" 
     language="fi">1</attribute> 
    <attribute type="status" datatype="ST">1</attribute> 
    <attribute type="codetype" datatype="ST">1</attribute> 
    <attribute type="relatesto" datatype="ST">BASE</attribute> 
    <attribute type="relatestoname" datatype="ST">BASE</attribute> 
    <attribute type="hierarchical" datatype="ST">0</attribute> 
    <termitementry id="1010110" language="fi" 
     createdate="2007-10-25T15:24:17.0" 
     begindate="2003-01-01T00:00:01.0" 
     expirationdate="2004-12-31T23:59:59.0" 
     lastmodifieddate="2007-10-25T17:06:25.0" 
     lastmodifiedby="Admin"> 
    <attribute type="status" datatype="ST">1</attribute> 
    <attribute type="shortname" datatype="ST" language="fi">Whey protein</attribute> 
    <attribute type="longname" datatype="ST" language="fi" /> 
    <attribute type="abbreviation" datatype="ST" 
     language="fi">Raspberry</attribute> 
    <attribute type="hierarchylevel" datatype="ST">0</attribute> 
    <attribute type="parentid" datatype="ST" language="fi" /> 
    <attribute type="description" datatype="ST" language="fi" /> 
    <attribute type="owner" datatype="ST" 
     language="sv">Admin</attribute> 
    <attribute type="externallink" 
     datatype="CV" 
     begindate="2003-01-01T00:00:01.0" 
     expirationdate="2005-12-31T23:59:59.0" 
     ><codedvalue code="08" 
      codesystem="PUN" 
      codesystemversion="1" 
      referenceid="BASEpowder" /></attribute> 
    <attribute type="externallink" 
     datatype="CV" 
     begindate="2001-01-01T00:00:01.0" 
     expirationdate="2006-12-31T23:59:59.0" 
     ><codedvalue code="80112" 
      codesystem="PROTEIN" 
      codesystemversion="1" 
      referenceid="BASEprotein" /></attribute> 
    <attribute type="externallink" 
     datatype="CV" 
     begindate="2003-01-01T00:00:01.0" 
     expirationdate="2008-01-31T23:59:59.0" 
     ><codedvalue code="03" 
      codesystem="REF" 
      codesystemversion="1" 
      referenceid="BASEref" /></attribute> 
</termitementry 
></termsystem 
></body 
></arb:document 
></arb:result> 

我使用的XSLT是:

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

    <xsl:template match="termitementry"> 
     <xsl:element name="CodeRow"> 

      <xsl:element name="Code"> 
       <xsl:apply-templates select="@id" /> 
      </xsl:element> 

      <xsl:element name="Begindate"> 
       <xsl:apply-templates select="@begindate" /> 
      </xsl:element> 

      <xsl:element name="Expirationdate"> 
        <xsl:apply-templates select="@expirationdate" /> 
      </xsl:element> 

      <xsl:element name="Lastmodifiedby"> 
        <xsl:apply-templates select="@lastmodifiedby" /> 
      </xsl:element> 


     </xsl:element> 
    </xsl:template> 

    <xsl:template match="@id"> 
     <xsl:value-of select="." /> 
    </xsl:template> 

    <xsl:template match="@begindate"> 
     <xsl:value-of select="." /> 
    </xsl:template> 

    <xsl:template match="@expirationdate"> 
     <xsl:value-of select="." /> 
    </xsl:template> 

    <xsl:template match="@lastmodifiedby"> 
     <xsl:value-of select="." /> 
    </xsl:template> 

</xsl:stylesheet> 

,並用這個,我似乎只得到第一個節點後的屬性,但沒有什麼+我得到一些廢話,我正在使用http://chris.photobooks.com/xml/default.htm來測試東西

<transformiix:result> 
    Produced by CodeRows 4.2 


    1 
    1 
    1 
    BASE 
    BASE 
    0 
    <CodeRow> 
     <Code> 
      1010110 
     </Code> 
     <Begindate> 
      2003-01-01T00:00:01.0 
     </Begindate> 
     <Expirationdate> 
      2004-12-31T23:59:59.0 
     </Expirationdate> 
     <Lastmodifiedby> 
      Admin 
     </Lastmodifiedby> 
    </CodeRow> 
</transformiix:result> 

誰能幫如何走出休息嗎?

我希望得到一個XML與基本結構:

<coderow> 
    <Code> 
      1010110 
    </Code> 
    <Begindate> 
     2003-01-01 (only want the 10 first digits of 2003-01-01T00:00:01.0, preferably I would just to have the digits so it looks like 20030101) 
    </Begindate> 
    <Shortname> 
     Whey protein 
    </Shortname> 
    <BASEpowder> 
     08 
    <BASEpowder> 
    <BASEprotein> 
     80112 
    </BASEprotein> 

</CodeRow> 

又是如何得出我出去,我不能看到我所做的任何templete它「通過CodeRows 4.2等。公司生產的」?

+2

問題不清楚,請更新輸出與輸入中的實際值XML。 –

回答

2

在回答你的問題「我怎麼會出來'由CodeRows 4.2等生產''我不能看到我爲它做了任何模板?」答案是因爲你還沒有製作任何模板對於其他元素,XSLT將使用默認的模板匹配。此默認行爲將處理所有節點的子節點,或者在案例或文本節點中,它會將這些輸出爲文本。

XSLT將開始我眺望遠處爲頂級文檔元素相匹配的模板,因爲你沒有指定一個模板匹配,默認行爲踢。你第一個模板匹配termitementry並通過它發現它已經執行了所有父元素的默認匹配。

要停止這種情況的發生,並直接跳轉到termitemtentry節點,你應該做這樣的事情

<xsl:template match="/"> 
    <xsl:apply-templates select="//termitementry" /> 
</xsl:template> 

此外,請注意您的現有代碼把屬性轉換成元素可以簡化。相反,這樣做

<xsl:element name="Code"> 
    <xsl:apply-templates select="@id" /> 
</xsl:element> 

的你可以做這個

<Code> 
    <xsl:value-of select="@id"/> 
</Code> 

這意味着你可以刪除匹配所有屬性的模板。

你可能只需要爲你的「外部」鏈接元素,模板匹配,你可以做這樣的事情

<xsl:template match="attribute[@type='externallink']"> 
    <xsl:element name="{codedvalue/@referenceid}"> 
     <xsl:value-of select="codedvalue/@code"/> 
    </xsl:element> 
</xsl:template> 

以下是完整的XSLT

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

    <xsl:template match="/"> 
     <xsl:apply-templates select="//termitementry"/> 
    </xsl:template> 

    <xsl:template match="termitementry"> 
     <CodeRow> 
     <Code> 
      <xsl:value-of select="@id"/> 
     </Code> 
     <Begindate> 
      <xsl:value-of select="@begindate"/> 
     </Begindate> 
     <Expirationdate> 
      <xsl:value-of select="@expirationdate"/> 
     </Expirationdate> 
     <Lastmodifiedby> 
      <xsl:value-of select="@lastmodifiedby"/> 
     </Lastmodifiedby> 
     <xsl:apply-templates select="attribute[@type='externallink']"/> 
     </CodeRow> 
    </xsl:template> 

    <xsl:template match="attribute[@type='externallink']"> 
     <xsl:element name="{codedvalue/@referenceid}"> 
     <xsl:value-of select="codedvalue/@code"/> 
     </xsl:element> 
    </xsl:template> 
</xsl:stylesheet> 

當適用於您的樣品XML,以下是輸出

<CodeRow> 
    <Code>1010110</Code> 
    <Begindate>2003-01-01T00:00:01.0</Begindate> 
    <Expirationdate>2004-12-31T23:59:59.0</Expirationdate> 
    <Lastmodifiedby>Admin</Lastmodifiedby> 
    <BASEpowder>08</BASEpowder> 
    <BASEprotein>80112</BASEprotein> 
    <BASEref>03</BASEref> 
</CodeRow> 
+0

我<3 U,我還沒有弄清楚xslt paraser是如何處理文檔的,直到您解釋爲止,現在我想知道我是否想分析日期,以便只取出我需要的第一個數字來爲它做個模板。想要2003-01-01T00:00:01.0只會是20030101 – Kkloe

+0

這並不難。例如,在XSLT1.0中,可以使用'substring'和'translate'的組合。如果你不能解決這個問題,請隨時提出一個關於日期格式的全新問題,我相信它會很快得到回覆:) –

+0

還有一件事,即使用哪種XSLT版本,XSLT1.0或XSLT2 .0? – Kkloe

相關問題