2017-07-15 150 views
0

中存在動態節點名稱的節點的子節點此問題。如何訪問XSLT

我有這樣的XML:

<Document> 
    <Type>ABC</Type> 
    <Header> 
    <Date>15-01-2017</Date> 
    <Time>11:00 AM</Time> 
    </Header> 
    <Body> 
    <Name>Juan</Name> 
    <Age>10</Age> 
    <Address> 
     <City>City</City> 
     <Country>Country</Country> 
     <Block>Block</Block> 
    </Address> 
    </Body> 
</Document> 

,我有這個XSLT:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl" 
> 
    <xsl:output method="xml" indent="yes"/> 
    <xsl:variable name ="DocumentType" select ="//Document/Type" /> 

    <xsl:template match ="Document"> 
    <Root> 
     <xsl:apply-templates select ="Header" /> 
     <xsl:element name="Data{$DocumentType}"> 
     <xsl:call-template name="Data"> 
      <xsl:with-param name="type" select ="$DocumentType" /> 
     </xsl:call-template> 
     </xsl:element> 
    </Root> 
    </xsl:template> 

    <xsl:template name ="Data"> 
    <xsl:param name="type" /> 
    <Name> 
     <xsl:value-of select ="Body/Name" /> 
    </Name> 
    <Age> 
     <xsl:value-of select ="Body/Age" /> 
    </Age> 
    <xsl:element name="Address{$type}"> 
     <City> 
     <xsl:value-of select ="City"/> 
     </City> 
     <Country> 
     <xsl:value-of select ="Country"/> 
     </Country> 
     <Block> 
     <xsl:value-of select ="Block"/> 
     </Block> 
    </xsl:element> 
    </xsl:template> 

    <xsl:template match ="Header"> 
    <Header> 
     <DateCreated> 
     <xsl:value-of select ="Date"/> 
     </DateCreated> 
     <TimeCreated> 
     <xsl:value-of select ="Time"/> 
     </TimeCreated> 
    </Header> 
    </xsl:template> 
    <xsl:template match="@* | node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@* | node()"/> 
    </xsl:copy> 
    </xsl:template> 

我的問題是我不能訪問XML中的地址的子節點的值,我只看到這個:

<Root> 
    <Header> 
    <DateCreated>15-01-2017</DateCreated> 
    <TimeCreated>11:00 AM</TimeCreated> 
    </Header> 
    <DataABC> 
    <Name>Juan</Name> 
    <Age>10</Age> 
    <AddressABC> 
     <City></City> 
     <Country></Country> 
     <Block></Block> 
    </AddressABC> 
    </DataABC> 
</Root> 

任何人都可以幫助我向我展示我的錯誤。

感謝

+0

我很困惑爲什麼你將模板應用到'Header',但是選擇調用一個命名模板來處理'Body'。當然,最後加上的身份轉換模板並沒有做任何事情。 –

回答

1

你的錯誤已經在邁克爾凱的回答中指出。

我想提出一種替代方法 - 一個需要少了很多工作:

XSLT 1.0

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

<xsl:variable name="DocumentType" select="/Document/Type" /> 

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

<xsl:template match="/Document"> 
    <Root> 
     <xsl:apply-templates select="Header | Body"/> 
    </Root> 
</xsl:template> 

<xsl:template match="Body"> 
    <xsl:element name="Data{$DocumentType}"> 
     <xsl:apply-templates/> 
    </xsl:element> 
</xsl:template> 

<xsl:template match="Date | Time"> 
    <xsl:element name="{name()}Created"> 
     <xsl:apply-templates/> 
    </xsl:element> 
</xsl:template> 

<xsl:template match="Address"> 
    <xsl:element name="Address{$DocumentType}"> 
     <xsl:apply-templates/> 
    </xsl:element> 
</xsl:template> 

</xsl:stylesheet> 

注意,全局變量是任何模板訪問並執行不需要作爲參數發送。

+0

是否可以使用像「Address {$ DocumentType}」這樣的字符串作爲模板名稱或匹配?因爲我可能需要這樣的臨時工 – zyberjock

+0

https://stackoverflow.com/questions/45108406/need-to-replace-a-value-in-the-match-part-of-xslt#comment77188621_45108406不知道如何這涉及到你的問題上面。 –

1

就象使用Body/Name得到名稱,就可以使用Body/Address/City獲得市(因爲上下文項是Document元素)。

但是,您的代碼有點單片。在地址元素上執行xsl:apply-templates可能會更好,然後使用match="Address"的模板規則,其中您可以使用select="City"來選擇相對於AddressCity