首页 > 解决方案 > Xpath - 选择和读取所有子节点的值,无论名称如何

问题描述

我正在研究将 ISO 19139-2 (2009) XML 文档转换为一些文本字符串的 xsl 转换(GeoNetwork 模式插件的index-fields/index.xsl,而后者又由 ElasticSearch 实例读取)。在特定元素中,我试图:

  1. 选择具有特定确切节点名称的该节点的所有后代
  2. 获取上述节点的所有直接子节点,除了具有特定名称的节点
  3. 打印上述节点的名称和值

但是,我似乎从未从转换中获得任何输出。通过查看其他示例,我觉得我一定遗漏了一些非常简单的东西,但我不能完全理解它。

我尝试了几种不同的方法,主要是围绕如何放置无命名空间节点、我对某些路径的具体程度以及句点/当前节点位置元素的使用。

据我所知,我选择了所有可用的 MI_AcquisitionInformation,然后从那里寻找具有指定名称的孩子,然后获取他们的孩子,加上应用特定的名称条件,然后读出这些节点的值及其名字。但相反,我什么也没得到。

<xsl-for-each select="gmi:acquisitionInformation/*">            
  <xsl:for-each select=".//gmi:MI_Operation/*[name() != 'gmi:platform']">
    <operationDetails> <!-- lines like this, without a namespace, end up being the name of the 'bundle' holding the resulting output' -->
      <xsl:value-of select="name()"/>:<xsl:value-of select="."/>
    </operationDetails>
  </xsl:for-each>       

  <xsl:for-each select=".//gmi:MI_Platform/*[name() != 'gmi:instrument']">
    <platformDetails>
      <xsl:value-of select="name()"/>:<xsl:value-of select="."/>
    </platformDetails>
  </xsl:for-each>        

  <xsl:for-each select=".//gmi:MI_Instrument">
    <instrumentDetails>
      <xsl:value-of select="name()"/>:<xsl:value-of select="."/>
    </instrumentDetails>
  </xsl:for-each>        
</xsl-for-each>

一个具体的详细示例是...

<gmi:acquisitionInformation>
  <gmi:MI_AcquisitionInformation>
    <gmi:instrument>
      <gmi:MI_Instrument>
        <gmi:identifier>
          (additional content in nodes)
        </gmi:identifier>
        <gmi:type>
          <gco:CharacterString> Text </gco:CharacterString>
        </gmi:type>
      </gmi:MI_Instrument>
    </gmi:instrument>
    <gmi:operation>
      <gmi:MI_Operation>
        <gmi:identifier>
          (additional content in nodes)
        </gmi:identifier>        
        <gmi:citation>
          (additional content in nodes)
        </gmi:citation>
        <gmi:status>
          <gmd:MD_ProgressCode (content in attributes)/>
        </gmi:status>
        <gmi:platform>
          <gmi:MI_Platform>
            <gmi:identifier>
              (additional content in nodes)
            </gmi:identifier>
            <gmi:description>
              <gco:CharacterString> Text </gco:CharacterString>
            </gmi:description>
            <gmi:instrument>
              <gmi:MI_Instrument>
                <gmi:identifier>
                  (additional content in nodes)
                </gmi:identifier>
                <gmi:type>
                  <gco:CharacterString> Text </gco:CharacterString>
                </gmi:type>
              </gmi:MI_Instrument>
            </gmi:instrument>
          </gmi:MI_Platform>
        </gmi:platform>
      </gmi:MI_Operation>
    </gmi:operation>
    <gmi:platform>
      <gmi:MI_Platform>
        <gmi:identifier>
          (additional content in nodes)
        </gmi:identifier>
        <gmi:description>
          <gco:CharacterString> Text </gco:CharacterString>
        </gmi:description>
        <gmi:instrument>
          <gmi:MI_Instrument>
            <gmi:identifier>
              (additional content in nodes)
            </gmi:identifier>
            <gmi:type>
              <gco:CharacterString> Text </gco:CharacterString>
            </gmi:type>
          </gmi:MI_Instrument>
        </gmi:instrument>
      </gmi:MI_Platform>
    </gmi:platform>
  </gmi:MI_AcquisitionInformation>
</gmi:acquisitionInformation>

对于上面的示例,我希望得到类似的结果。

<operationDetails>
  gmi:identifier:(the additional content from its child nodes)
  gmi:citation:(the additional content from its child nodes)
  gmi:status:(Unsure? maybe nothing because the values are in attributes here?)
<!-- note here that there is no platform information -->
</operationDetails>
<platformDetails>
  gmi:identifier:(for the one inside the operation)
  gmi:description:(for the one inside the operation)
</platformDetails>
<platformDetails>
  gmi:identifier:(for the one inside MI_AcquisitionInformation)
  gmi:description:(for the one inside MI_AcquisitionInformation)
<!-- note here that there is no instrument information -->
</platformDetails>
<instrumentDetails>
  gmi:identifier:(for the one inside MI_AcquisitionInformation)
  gmi:type:(for the one inside MI_AcquisitionInformation)
</instrumentDetails>
<instrumentDetails>
  for the one inside platform inside the operation, same sort of info as above...
</instrumentDetails>
<instrumentDetails>
  for the one inside the platform inside MI_AcquisitionInformation, same sort of info as above...
</instrumentDetails>

大多数情况下,对于包含 MI_Operation、MI_Platform 和/或 MI_Instrument 的记录,我希望在 ElasticSearch 中看到名为 (something)Details 的内容,但这是在另一个处理步骤之后。

但如前所述,我什么也没得到,也没有错误消息——所以大概我只是在错误的节点上选择,而不是在代码中实际出错。

标签: xmlxpathxslt-2.0geonetwork

解决方案


错字修复和我昨晚意识到的更好的方法相结合似乎是解决方案。很抱歉这不是一个完整的 xsl 文档,但解决方案的要点是......

      <xsl:for-each select="gmi:acquisitionInformation/*">        
        <xsl:for-each select=".//gmi:MI_Operation">
          <operationDetails>{
            <xsl:for-each select="./*[name() != 'gmi:platform']">
              &quot;<xsl:value-of select="name()"/>&quot;:&quot;<xsl:value-of select="."/>&quot;,
            </xsl:for-each>
          }</operationDetails>
        </xsl:for-each>       

        <xsl:for-each select=".//gmi:MI_Platform">
          <platformDetails>{
            <xsl:for-each select="./*[name() != 'gmi:instrument']">
              &quot;<xsl:value-of select="name()"/>&quot;:&quot;<xsl:value-of select="."/>&quot;,
            </xsl:for-each>
          }</platformDetails>
        </xsl:for-each>        

       <xsl:for-each select=".//gmi:MI_Instrument">
          <instrumentDetails>{
            <xsl:for-each select="./*">
              &quot;<xsl:value-of select="name()"/>&quot;:&quot;<xsl:value-of select="."/>&quot;,
            </xsl:for-each>
          }</instrumentDetails>
        </xsl:for-each>      
      </xsl:for-each>

对于想要在 GeoNetwork 中使用它的人,我将它直接放在<xsl:for-each select="gmd:distributionInfo/*>我的架构插件中的 gmd:distributionInfo 部分(以 line 开头)下index-fields\index.xsl。如果您更改根模板匹配以适应,这将拾取其中的gmi:acquisitionInformation块。gmi:MI_Metadatagmi:MI_Metadata


推荐阅读