我似乎找不到确切的方法。我有这个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>
,我想根据内部节点中找到的字符串从特定名称节点中提取域。如您所见,我在节点内部有多个名称。通过以下bash文件,我可以提取name的第一个实例
#!/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,则拉出名称,等等。
希望如此。
谢谢
答案 0 :(得分:1)
您当前的XPath表达式,为:
/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="198.18.133.1"]/name">
<xsl:call-template name="value-of-template">
<xsl:with-param name="select" select="."/>
</xsl:call-template>
<xsl:value-of select="' '"/>
</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()>1]">
<xsl:value-of select="' '"/>
<xsl:value-of select="."/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>