第二个文件中的XSL密钥查找&替换元素

时间:2017-10-26 14:25:40

标签: attributes key match xslt-2.0

我有两个xml文件:

Source.xml

<osm>
  <count>
    <tag k="total" v="1560"/>
  </count>
  <node>
    <tag k="fhrs:id" v="111111"/>
  </node>
  <node>
    <tag k="fhrs:id" v="222222"/>
    <tag k="addr:postcode" v="XXX XXX"/>
  </node>
  <node>
    <tag k="fhrs:id" v="333333"/>
    <tag k="addr:postcode" v="YYY YYY"/>
  </node>
  <way>
    <tag k="fhrs:id" v="444444"/>
  </way>
  <way>
    <tag k="fhrs:id" v="555555"/>
    <tag  v="ZZZ ZZZ"/>
  </way>
</osm>

Lookup.xml

<FHRSEstablishment>
    <EstablishmentCollection>
        <EstablishmentDetail>
            <FHRSID>111111</FHRSID>
            <PostCode>BA1 111</PostCode>
        </EstablishmentDetail>
        <EstablishmentDetail>
            <FHRSID>333333</FHRSID>
            <PostCode>BA2 222</PostCode>
        </EstablishmentDetail>
        <EstablishmentDetail>
            <FHRSID>555555</FHRSID>
            <PostCode>BA3 333</PostCode>
        </EstablishmentDetail>
    </EstablishmentCollection>
</FHRSEstablishment>

我希望使用source.xml中@v属性的相应k=fhrs:id值与lookup.xml中的FHRSID节点值进行比较,以生成修订版的源代码。 XML。

找到匹配项后,应复制Postcode节点的值,以使用属性@v替换标记元素的k="addr:postcode"属性的值。

这是XSL fille:
     

<xsl:key name="FHRSID-key" match="FHRSID" use="node()"/>
<xsl:variable name="lookup-doc" select="doc('lookup.xml')"/>

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

<xsl:template match="*/tag[@v and key('FHRSID-key', @v, $lookup-doc)]">
    <xsl:copy>
        <xsl:attribute name="k">addr:postcode</xsl:attribute>
        <xsl:attribute name="v" select="key('FHRSID-key', @v, $lookup-doc)/../PostCode/node()"/>
  </xsl:copy>
</xsl:template>

这是当前的输出

<osm>
   <count>
      <tag k="total" v="1560"/>
   </count>
   <node>
      <tag k="addr:postcode" v="BA1 111"/>
   </node>
   <node>
      <tag k="fhrs:id" v="222222"/>
      <tag k="addr:postcode" v="XXX XXX"/>
   </node>
   <node>
      <tag k="addr:postcode" v="BA2 222"/>
      <tag k="addr:postcode" v="YYY YYY"/>
   </node>
   <way>
      <tag k="fhrs:id" v="444444"/>
   </way>
   <way>
      <tag k="addr:postcode" v="BA3 333"/>
      <tag k="addr:postcode" v="ZZZ ZZZ"/>
   </way>
</osm>

这是所需的输出:

<osm>
    <count>
    <tag k="total" v="1560"/>
    </count>
    <node>
    <tag k="fhrs:id" v="111111"/>
    <tag k="addr:postcode" v="BA1 111"/>
    </node>
    <node>
    <tag k="fhrs:id" v="222222"/>
    <tag k="addr:postcode" v="XXX XXX"/>
    </node>
    <node>
    <tag k="fhrs:id" v="333333"/>
    <tag k="addr:postcode" v="BA2 222"/>
  </node>
  <way>
    <tag k="fhrs:id" v="444444"/>
  </way>
  <way>
    <tag k="fhrs:id" v="555555"/>
    <tag k="addr:postcode" v="BA3 333"/>
  </way>
</osm>

正如您所看到的那样,它将'fhrs:id'元素替换为复制的邮政编码元素,而不是原始的k="addr:postcode"

附带问题:

match="*/tag[@v and key('FHRSID-key', @v, $lookup-doc)]"

第一次出现的@v实际上是在做什么吗?

对我而言,此匹配似乎正在搜索所有标记元素。如果是这样,那么如何仅限于仅具有k="addr:postcode"属性的人。

建议任何其他改进,请随意。

1 个答案:

答案 0 :(得分:0)

更改代码以匹配父

<xsl:key name="FHRSID-key" match="EstablishmentDetail" use="FHRSID"/>
<xsl:variable name="lookup-doc" select="doc('lookup.xml')"/>

<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>

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

<xsl:template match="*[tag[@k = 'fhrs:id' and key('FHRSID-key', @v, $lookup-doc)]]">
    <xsl:copy>
        <xsl:apply-templates select="@* , node() except tag[@k = 'addr:postcode']"/>
        <tag k="addr:postcode" v="{key('FHRSID-key', tag[@k = 'fhrs:id']/@v, $lookup-doc)/PostCode}"/>
    </xsl:copy>
</xsl:template>

给出

<osm>
   <count>
      <tag k="total" v="1560"/>
   </count>
   <node>
      <tag k="fhrs:id" v="111111"/>
      <tag k="addr:postcode" v="BA1 111"/>
   </node>
   <node>
      <tag k="fhrs:id" v="222222"/>
      <tag k="addr:postcode" v="XXX XXX"/>
   </node>
   <node>
      <tag k="fhrs:id" v="333333"/>
      <tag k="addr:postcode" v="BA2 222"/>
   </node>
   <way>
      <tag k="fhrs:id" v="444444"/>
   </way>
   <way>
      <tag k="fhrs:id" v="555555"/>
      <tag v="ZZZ ZZZ"/>
      <tag k="addr:postcode" v="BA3 333"/>
   </way>
</osm>

唯一的问题似乎是<tag v="ZZZ ZZZ"/>元素。我不确定复制或不复制现有内容的标准是什么,如果您只想保留tag k="fhrs:id"然后将最后一个模板更改为

<xsl:template match="*[tag[@k = 'fhrs:id' and key('FHRSID-key', @v, $lookup-doc)]]">
    <xsl:copy>
        <xsl:apply-templates select="@* , tag[@k = 'fhrs:id']"/>
        <tag k="addr:postcode" v="{key('FHRSID-key', tag[@k = 'fhrs:id']/@v, $lookup-doc)/PostCode}"/>
    </xsl:copy>
</xsl:template>