开发者

XLST using lookups

开发者 https://www.devze.com 2023-03-27 02:52 出处:网络
I\'m trying to transform an XML document into another XML document. I\'ve tried various approaches, none of which produced the desired target XML document.

I'm trying to transform an XML document into another XML document. I've tried various approaches, none of which produced the desired target XML document.

I have a hypothetical input XML document like this:

<rows>
 <row>
  <name>ON</name>
  <description/>
 </row>
 <row>
  <name>NY</name>
  <description/>
 </row>
</rows>

I also have two lookups:

<loc:locations>
 <loc:location>
  <loc:code>ON</loc:code>
  <loc:value>Ontario</loc:value>
 </loc:location>
 <loc:location>
  <loc:code>NY</loc:code>
  <loc:value>New York</loc:value>
 </loc:location>
</loc:locations>

<des:descriptions>
 <des:description>
  <des:code>ON</des:code>
  <des:value>Ontario is a province in Canada</des:value>
 </des:description>
 <des:description>
  <des:code>NY</des:code>
  <des:value>New York is a state in the USA</des:value>
 </des:description>
</des:descriptions>

I would like the input XML to be transformed into th开发者_如何学Pythonis target XML:

<places>
 <place>
  <name>Ontario</name>
  <description>Ontario is a province in Canada</description>
 </place>
 <place>
  <name>New York</name>
  <description>New York is a state in the USA</description>
 </place>
</places>

What is the XSLT that would accomplish this? Thanks!


Just to clean-up things for readability, because you adopted namespace convention, you can also conveniently save all lookup data into a single variable. Also use current() to access name of current node. Avoid //.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:loc="http://sample.com/location"
    xmlns:des="http://sample.com/description"
    version="1.0">

    <xsl:variable name="lookup" 
        select="document('locations.xml')/loc:locations/loc:location
        | document('descriptions.xml')/des:descriptions/des:description"/>

    <xsl:template match="rows">
        <places>
            <xsl:apply-templates/>
        </places>
    </xsl:template>

    <xsl:template match="row">
        <place>
            <name>
                <xsl:value-of select="$lookup[loc:code=current()/name]/
                    loc:value"/>
            </name>
            <description>
                <xsl:value-of select="$lookup[des:code=current()/name]/
                    des:value"/>
            </description>
        </place>
    </xsl:template>

</xsl:stylesheet>


This worked for me with Xalan:

<xsl:transform 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
  xmlns:loc="http://sample.com/location"
  xmlns:des="http://sample.com/description"
  version="1.0">

 <xsl:output method="xml"/>

 <xsl:variable name="locations" select="document('locations.xml')/loc:locations/loc:location"/>
 <xsl:variable name="descriptions" select="document('descriptions.xml')/des:descriptions/des:description"/>

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

 <xsl:template match="//row">
  <xsl:variable name="name" select="name/text()"/>
  <place>
    <name><xsl:value-of select="$locations[loc:code = $name]/loc:value"/></name>
    <description><xsl:value-of select="$descriptions[des:code = $name]/des:value"/></description>
  </place>
 </xsl:template>

</xsl:transform>
0

精彩评论

暂无评论...
验证码 换一张
取 消