代码之家  ›  专栏  ›  技术社区  ›  Jason Murray

使用bash脚本[duplicate]从XML节点提取字符串

  •  0
  • Jason Murray  · 技术社区  · 6 年前

    我似乎找不到确切的方法。我有这个XML文件

    <session>
      <translations>
       <translation>
          <inside>198.18.133.1</inside>
          <name>adfs.domain1.com</name>
        </translation>
        <translation>
          <inside>198.18.135.60</inside>
          <name>hds.domain2.com</name>
        </translation>
       </translations>
     </session>
    

    #!/bin/bash
    domain="$(echo "cat /session/translations/translation/name/text()" | xmllint --nocdata --shell session.xml | sed '1d;$d')"
    domain="${domain:5}"
    printf '%s\n' "Domain is: $domain"
    

    这将给我domain1.com。

    有时我可能有更多或更少的翻译,他们并不总是在同一顺序。因此,如果内部节点匹配198.18.133.1,我需要一种方法来拉取名称;如果内部节点匹配198.18.135.60,我需要一种方法来拉取名称,以此类推。

    希望这有意义。

    谢谢

    1 回复  |  直到 6 年前
        1
  •  1
  •   Charles Duffy    6 年前

    /session/translations/translation/name/text()
    

    /session/translations/translation[inside="198.18.133.1"]/name/text()
    

    …以执行所需的过滤。


    使用XMLStarlet而不是XMLLint执行此操作可能更像:

    xmlstarlet sel -t -m '/session/translations/translation[inside="198.18.133.1"]/name' -v . -n
    

    如果添加 -C sel 子命令,它将发出XSLT模板,该模板将在引擎盖下进行计算,您可以使用它在任何地方运行 xsltproc 已安装,包括不带XMLStarlet的系统:

    <?xml version="1.0"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exslt="http://exslt.org/common" version="1.0" extension-element-prefixes="exslt">
      <xsl:output omit-xml-declaration="yes" indent="no"/>
      <xsl:template match="/">
        <xsl:for-each select="/session/translation/translation[inside=&quot;198.18.133.1&quot;]/name">
          <xsl:call-template name="value-of-template">
            <xsl:with-param name="select" select="."/>
          </xsl:call-template>
          <xsl:value-of select="'&#10;'"/>
        </xsl:for-each>
      </xsl:template>
      <xsl:template name="value-of-template">
        <xsl:param name="select"/>
        <xsl:value-of select="$select"/>
        <xsl:for-each select="exslt:node-set($select)[position()&gt;1]">
          <xsl:value-of select="'&#10;'"/>
          <xsl:value-of select="."/>
        </xsl:for-each>
      </xsl:template>
    </xsl:stylesheet>