代码之家  ›  专栏  ›  技术社区  ›  DaveF

在第二个文件和替换元素中查找XSL键

  •  0
  • DaveF  · 技术社区  · 7 年前

    我有两个xml文件:

    来源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>
    

    查找。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>
    

    我希望使用相应的 @v 的价值 k=fhrs:id FHRSID 查找中的节点值。xml生成源代码的修订版本。xml。

    当找到匹配项时 Postcode 应跨节点复制节点以替换 @五、 k="addr:postcode" .

    这是XSL文件:

    <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' 具有复制的postcode元素的元素,而不是原始的 k=“地址:邮政编码” .

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

    是第一次出现 @五、 实际上在做什么?

    在我看来,这个匹配似乎是在搜索所有标记元素。如果是这样的话,如何限制只寻找那些只有 属性

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

    1 回复  |  直到 7 年前
        1
  •  1
  •   Martin Honnen    7 年前

    更改代码以匹配父级

    <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>