English 中文(简体)
使用 XSLT 进行非引用的过滤器成员节点
原标题:filtering non referenced member nodes using XSLT
  • 时间:2012-05-23 08:07:09
  •  标签:
  • xml
  • xslt

OpenStreetMap xml 文档由一组“节点”元素和一组“道路”元素组成(等等)。

“ 节点” 元素可以( 可选择) 嵌套“ 标签” 元素 。

“道路”元素由“节点”元素的定序列表组成,由嵌套元素“nd”引用,其属性“ref”指向“节点”元素中的属性“id”。

举例来说:

<?xml version="1.0" encoding="UTF-8"?>
<osm version="0.6" generator="CGImap 0.0.2">
  <node id="1726631203" lat="50.8500083" lon="4.3553223" visible="true" version="6" changeset="9938190" timestamp="2011-11-24T22:05:32Z"/>
  ...
  <way id="160611697" user="toSc" uid="246723" visible="true" version="1" changeset="11385198" timestamp="2012-04-22T14:57:19Z">
    <nd ref="1726631203"/>
    <nd ref="1726631223"/>
    <nd ref="1726631213"/>
    <nd ref="1726631205"/>
    <nd ref="1726631185"/>
    <nd ref="1726631203"/>
  </way>
  ...
</osm>

我的问题是,如何使用XSLT, 我能做以下的转变吗?

  • Filtering all the node elements that are not referenced by any way element.
  • Filtering the way elements that reference node elements not included in the source xml document.
  • Changing the attribute "visible" to "false", to any "node" element not having "tag" children elements.

生成 xml 中应保留任何其他元素。

最佳回答

My question is how, using XSLT, could I do the following transformation ?

  • 过滤所有未以任何方式被元素引用的节点元素 。

  • 过滤源 xml 文档中没有包含的引用节点元素元素的方式 。

  • 将属性“ 可见” 改为“ 假”, 改为“ 节点” 元素, 没有“ 标签” 子元素 。

<强 > 此转换完全满足所有三个要求:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:key name="kND-By-Ref" match="way/nd" use="@ref"/>
 <xsl:key name="kNodeById" match="node" use="@id"/>

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

 <xsl:template match="node[not(key( kND-By-Ref , @id))]"/>
 <xsl:template match="way[nd[not(key( kNodeById , @ref))]]"/>

 <xsl:template match="node[not(tag)]/@visible">
  <xsl:attribute name="visible">false</xsl:attribute>
 </xsl:template>
</xsl:stylesheet>

应用到此 XML 文档 (适当创建以包含每项要求的立案) 时 < strong > :

<osm version="0.6" generator="CGImap 0.0.2">
    <node id="1726631203" lat="50.8500083" lon="4.3553223" visible="true"
      version="6" changeset="9938190" timestamp="2011-11-24T22:05:32Z">
      <tag/>
 </node>
    <node id="1726631223" lat="50.8500083" lon="4.3553223" visible="true"
      version="6" changeset="9938190" timestamp="2011-11-24T22:05:32Z"/>
    <node id="ZZZZZZZ" lat="50.8500083" lon="4.3553223" visible="true"
      version="6" changeset="9938190" timestamp="2011-11-24T22:05:32Z"/>
    <way id="160611697" user="toSc" uid="246723" visible="true"
      version="1" changeset="11385198" timestamp="2012-04-22T14:57:19Z">
        <nd ref="1726631203"/>
        <nd ref="1726631223"/>
    </way>
    <way id="160611698" user="toSc" uid="246723" visible="true"
      version="1" changeset="11385198" timestamp="2012-04-22T14:57:19Z">
        <nd ref="1726631203"/>
        <nd ref="1726631223"/>
        <nd ref="1726631213"/>
        <nd ref="1726631205"/>
        <nd ref="1726631185"/>
        <nd ref="1726631203"/>
    </way>
</osm>

the wanted, 正确结果 (所有过滤都进行, visible 属性被转换为 node 元素中的 false ) 已经产生 :

<osm version="0.6" generator="CGImap 0.0.2">
   <node id="1726631203" lat="50.8500083" lon="4.3553223"
    visible="true" version="6" changeset="9938190" timestamp="2011-11-24T22:05:32Z">
      <tag/>
   </node>
   <node id="1726631223" lat="50.8500083" lon="4.3553223"
    visible="false" version="6" changeset="9938190" timestamp="2011-11-24T22:05:32Z"/>
   <way id="160611697" user="toSc" uid="246723" visible="true"
    version="1" changeset="11385198" timestamp="2012-04-22T14:57:19Z">
      <nd ref="1726631203"/>
      <nd ref="1726631223"/>
   </way>
</osm>

<强度 > 排除 :

  1. 身份规则被三个模板取代,每个模板执行三项要求中的一个。

  2. 有空机构的两个压倒一切的模板执行两个过滤要求。

  3. 我们使用密钥方便而高效地查找 node s, 其 id 属性和 d s 属性, 其 ref 属性。

  4. 在第三个压倒一切的模板中执行属性值重置要求。

问题回答

类似的东西应该有用:

<xsl:for-each select="//osm/node">
   <xsl:if test="//osm/way/nd[@ref=current()/@id]">

     <xsl:copy-of select=".">

   </xsl:if>
</xsl:for-each>

关键在于,如果节点返回为真实,如果 xpath 表达式返回一个或多个结果。 您可以使用相同的技术检查标签属性是否存在。 不幸的是, 如果您需要更改属性, 您需要手动复制其它属性( xsl: 复制除 < em> 可见 < / em > 属性以外的所有子属性, 而不是简单地使用 xsl: opplic- object ) 。

这似乎可行:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

  <xsl:template match="node">
    <xsl:if test="//osm/way/nd[@ref=current()/@id]">
      <xsl:choose>
        <xsl:when test="tag">
          <xsl:copy-of select="."/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:copy>
            <xsl:copy-of select="@*[not(local-name(.) =  visible )]"/>
            <xsl:attribute name="visible">false</xsl:attribute>
          </xsl:copy>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:if>
  </xsl:template>

</xsl:stylesheet>

xsl:if 测试从上一个答案复制, 并删除未引用的节点 。

xsl: chose 中的位元在标记儿童时设置假的可见属性。 这是更改属性值 < em> 的方法, 无需 单独复制所有属性; 但是它忽略了标记以外的任何子元素 。

我还没处理过路由元素的过滤问题





相关问题
how to represent it in dtd?

I have two element action and guid. guid is a required field when action is add. but when action is del it will not appear in file. How to represent this in dtd ?

.Net application configuration add xml-data

I need to add xml-content to my application configuration file. Is there a way to add it directly to the appSettings section or do I need to implement a configSection? Is it possible to add the xml ...

XStream serializing collections

I have a class structure that I would like to serialize with Xstream. The root class contains a collection of other objects (of varying types). I would like to only serialize part of the objects that ...

MS Word splits words in its XML format

I have a Word 2003 document saved as a XML in WordProcessingML format. It contains few placeholders which will be dynamically replaced by an appropriate content. But, the problem is that Word ...

Merging an XML file with a list of changes

I have two XML files that are generated by another application I have no control over. The first is a settings file, and the second is a list of changes that should be applied to the first. Main ...

How do I check if a node has no siblings?

I have a org.w3c.dom.Node object. I would like to see if it has any other siblings. Here s what I have tried: Node sibling = node.getNextSibling(); if(sibling == null) return true; else ...

Ordering a hash to xml: Rails

I m building an xml document from a hash. The xml attributes need to be in order. How can this be accomplished? hash.to_xml

热门标签