2017-07-15 17 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> 

私の間違いを誰かに見せてもらえますか?あなたが名前を取得するためにBody/Nameを使用したのと同様に(文脈項目がDocument要素であるため)

おかげ

+0

私はなぜ「Header」にテンプレートを適用するのか困惑しますが、「Body」を扱う名前付きテンプレートを呼び出すことを選択します。もちろん、最終的にタップされたアイデンティティ変換テンプレートは何もしません。 –

答えて

1

あなたの間違いは、マイケルケイの答えで既に指摘されています。

私は別のアプローチを提案したかった - はるかに少ない作業が必要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/Address/Cityを使用することができます。

ただし、コードは少しモノリシックです。 Address要素にxsl:apply-templatesを実行すると、match="Address"のテンプレートルールが有効になる場合があり、select="City"を使用してAddressを基準にCityを選択できます。

関連する問題