XSLT查找表:用查找中的元素替换元素

时间:2015-04-30 17:20:10

标签: xml xslt

我试图在XSLT中使用查找表。我有以下xmls:

data.xml中:

<?xml version="1.0"?>
<labels>
 <label>
  <name>Thomas Eliot</name>
  <address>
   <city>Hartford</city>
   <state id= "CT"/>
  </address>
 </label>
 <label>
  <name>Ezra Pound</name>
  <address>
   <city>Hailey</city>
    <state>
     <name>New York</name>
   </state>
  </address>
 </label>
</labels>

lookup.xml:

<?xml version="1.0"?>
<states>
 <state id="CT">
   <name>Connecticut</name>
 </state>
</states>

对于我想要的输出:

<labels>
 <label>
  <name>Thomas Eliot</name>
  <address>
   <city>Hartford</city>
   <state>
     <name>Connecticut</name>
   </state>
  </address>
 </label>
 <label>
  <name>Ezra Pound</name>
  <address>
   <city>Hailey</city>
   <state>
     <name>New York</name>
   </state>
  </address>
 </label>
</labels>

所以我想解析data.xml中的state id并从lookup.xml中复制相应元素的内容

我坚持使用以下xsl:

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

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

    <xsl:key name="lookupKey" match="state" use="@id"/>

    <xsl:variable name="lookupStore" select="document('lookup.xml')/states/"/>
    <xsl:template match="state[@id]">
        <xsl:apply-templates select="$lookupStore">
            <xsl:with-param name="current" select="."/>
        </xsl:apply-templates>
    </xsl:template>

    <xsl:template match="states">
        <xsl:param name="current"/>
        <xsl:value-of select="key('lookupKey', $current/address/state/@id)/."/>
    </xsl:template>
</xsl:transform>

为什么<xsl:template match="state[@id]">不适用?

1 个答案:

答案 0 :(得分:1)

找出差异:

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

<xsl:variable name="lookupStore" select="document('lookup.xml')/states"/>

<xsl:key name="lookupKey" match="state" use="@id"/>

<xsl:template match="state[@id]">
    <xsl:copy>
        <xsl:apply-templates select="$lookupStore">
            <xsl:with-param name="current" select="."/>
        </xsl:apply-templates>
    </xsl:copy>
</xsl:template>

<xsl:template match="states">
    <xsl:param name="current"/>
    <xsl:copy-of select="key('lookupKey', $current/@id)/name"/>
</xsl:template>

如果你愿意,你可以缩短整个事情:

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

<xsl:variable name="lookupdoc" select="document('lookup.xml')"/>

<xsl:key name="state-by-id" match="state" use="@id"/>

<xsl:template match="state/@id">
    <xsl:variable name="id" select="."/>
    <!-- switch context to the lookup document -->
    <xsl:for-each select="$lookupdoc">
        <xsl:copy-of select="key('state-by-id', $id)/name"/>
    </xsl:for-each>
</xsl:template>