使用具有多个条件的xpath从xml文件中提取值

时间:2015-10-15 05:19:52

标签: xml xslt xpath

我有这个xml:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<dev>
 <word string="test1" occurrences="39">
  <systems>
   <system name="paraview">
    <pos file="" part="noun" line="0" occ="39"/>
   </system>
  </systems>
 </word>
 <word string="Format" occurrences="39">
  <systems>
   <system name="paraview">
    <pos file="" part="verb" line="0" occ="40"/>
   </system>
  </systems>
 </word>
 <word string="Source" occurrences="16">
  <systems>
   <system name="paraview">
    <pos file="" part="verb" line="0" occ="16"/>
   </system>
  </systems>
 </word>
 <word string="p4" occurrences="1">
  <systems>
   <system name="Pstoedit">
    <pos file="" part="pronoun" line="0" occ="1"/>
   </system>
  </systems>
 </word>
 <word string="test1" occurrences="3">
  <systems>
   <system name="Pstoedit">
    <pos file="" part="noun" line="0" occ="3"/>
   </system>
  </systems>
 </word>
</dev>

我正在尝试提取这两个系统[paraview&amp; Pstoedit指定以下两个系统的条件应具有相同的完全字符串。 所以输出应该给我这里匹配的数量,并说是有两个系统,你想要的条件和匹配的字符串是test1

我尝试使用xmllint执行不同的命令,我认为最近的命令是最近的命令:

xmllint --xpath '//word/systems/system[@name="Pstoedit"][@name="paraview"]/pos[@part="noun"]' file.xml

如何在xpath中使用两个条件进行比较?请指教。

更新

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

<xsl:key name="paraview" match="system[@name='paraview']" use="ancestor::word/@string" />

<xsl:template match="/dev">
    <html>
        <body>
            <h2>Number of matched words</h2>
            <table border="1">
                <tr bgcolor="#9acd32">
                 <th>Total</th>   
                 <th>Words</th>
                </tr>
    <xsl:variable name="pairs" select="word/systems/system[@name='Pstoedit'][key('paraview', ancestor::word/@string)]" />
    <result>
        <tr>
        <count-pairs>          
           <td> <xsl:value-of select="count($pairs)"/> </td>
        </count-pairs>
        </tr>
        <tr>
        <match-strings>
           <td> <xsl:for-each select="$pairs"> </td>
                 <string>
            <td>   <xsl:value-of select="ancestor::word/@string"/> </td>
                </string>
            </tr>
            </xsl:for-each>
        </match-strings>
    </result>
    </table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

这是我得到的结果: results 我需要将它们安排在基于以前的xls和html代码的表中,如:

template

2 个答案:

答案 0 :(得分:0)

你可以试试这个XPath吗?

"//word/systems/system[@name='Pstoedit']/pos[@part='noun']|//word/systems/system[@name='paraview']/pos[@part='noun']"

这将为您提供具有part = noun

的Pstoedit或paraview系统

答案 1 :(得分:0)

  

我正在尝试提取这两个系统[paraview&amp; Pstoedit]那个   指定以下条件,这两个系统都应该   有完全相同的字符串。

您可以选择具有匹配Pstoedit系统的所有word系统(或者更确切地说是他们的祖先paraview):

/dev/word[systems/system/@name='Pstoedit'][@string=/dev/word[systems/system/@name='paraview']/@string]
  

输出应该在这里给我匹配的数量并说“是”   有两个系统,条件是你想要的......

好吧,每个选定的节点代表一个,所以:

2 * count ( $theabovexpression )

将为您提供所涉及节点的总数。

  

...匹配的字符串是test1

我认为没有办法单独在XPath中执行此操作。请记住,可能有多个对,并且每个匹配的字符串可能不同。但是,在XSLT中,您可以执行以下操作:

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

<xsl:key name="paraview" match="system[@name='paraview']" use="ancestor::word/@string" />

<xsl:template match="/dev">
    <xsl:variable name="pairs" select="word/systems/system[@name='Pstoedit'][key('paraview', ancestor::word/@string)]" />
    <result>
        <count-pairs>
            <xsl:value-of select="count($pairs)"/>
        </count-pairs>
        <match-strings>
            <xsl:for-each select="$pairs">
                <string>
                    <xsl:value-of select="ancestor::word/@string"/>
                </string>
            </xsl:for-each>
        </match-strings>
    </result>
</xsl:template>

</xsl:stylesheet>

返回:

<?xml version="1.0" encoding="UTF-8"?>
<result>
  <count-pairs>1</count-pairs>
  <match-strings>
    <string>test1</string>
  </match-strings>
</result>

编辑:

  

我只想要一个表格中的字符串列表和总计数   两列

以这种方式尝试:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" version="1.0" encoding="utf-8" indent="yes"/>

<xsl:key name="paraview" match="system[@name='paraview']" use="ancestor::word/@string" />

<xsl:template match="/dev">
    <xsl:variable name="pairs" select="word/systems/system[@name='Pstoedit'][key('paraview', ancestor::word/@string)]" />
    <xsl:variable name="count-pairs" select="count($pairs)" />
    <table border="1">
        <tr>
            <th>Strings</th>
            <th>Total</th>
        </tr>
        <xsl:for-each select="$pairs">
            <tr>
                <td><xsl:value-of select="ancestor::word/@string"/></td>
                <xsl:if test="position() = 1">
                    <td rowspan="{$count-pairs}">
                        <xsl:value-of select="$count-pairs"/>
                    </td>
                </xsl:if>
            </tr>
        </xsl:for-each>
    </table>
</xsl:template>

</xsl:stylesheet>

这将返回(例如,当找到两个匹配对时):

<table border="1">
   <tr>
      <th>Strings</th>
      <th>Total</th>
   </tr>
   <tr>
      <td>stringone</td>
      <td rowspan="2">2</td>
   </tr>
   <tr>
      <td>stringtwo</td>
   </tr>
</table>

您的浏览器应呈现为:

enter image description here