使用XSLT / XPATH选择具有特定值的子元素的元素

时间:2013-09-27 16:28:07

标签: xslt xpath

我有一个大的(200k行)XML文件作为工具的报告(在VSS数据库上报告)。它包含大量<file>元素,如下所示:

<file>
 <name>file.bat</name>
 <version>111</version>
 <checkedout>No</checkedout>
 <binary>Text</binary>
 <vss_path>$/Code/file.bat</vss_path>
 <original_path>C:\code\file.bat</original_path>
 <action>Labeled &apos;1.2.3.4&apos;</action>
 <date>27/09/2013 09:08:00</date>
 <comment></comment>
 <label>1.2.3.4</label>
 <label_comment></label_comment>
 <user>John</user>
 <shared_links>
  <shared_link>$/Beta_1</shared_link>
  <shared_link>$/Branches/New_Feature</shared_link>
 </shared_links>
</file>

我想找到 <file>元素,其中至少有一个<shared_link>以“$ / Beta”开头/前缀。

在理想的世界中,我想要的每个匹配元素都是<name><vss_path>和(匹配)<shared_link>部分,但这并不完全重要。

我不熟悉XSLT / XPATH,但相信那些可以做这样的事情吗?

2 个答案:

答案 0 :(得分:1)

使用

<xsl:template match="/">
  <xsl:apply-templates select="//file[shared_links/shared_link[starts-with(., '$/Beta')]]"/>
</xsl:template>

<xsl:template match="file">
  <xsl:copy-of select="name | vss_path | shared_links/shared_link"/>
</xsl:template>

输出这些元素。然而,结果是一个带有多个顶级元素的XML片段,如果你想要一个XML文档,那么将第一个模板更改为

<xsl:template match="/">
  <root>
  <xsl:apply-templates select="//file[shared_links/shared_link[starts-with(., '$/Beta')]]"/>
  </root>
</xsl:template>

答案 1 :(得分:1)

这个XSLT样式表:

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

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

  <xsl:template match="root">
    <xsl:copy>
      <xsl:apply-templates select="file[shared_links[shared_link[starts-with(., '$/Beta')]]]"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="file">
    <xsl:copy>
      <xsl:apply-templates select="name | vss_path | shared_links"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="shared_links">
    <xsl:copy>
      <xsl:apply-templates select="shared_link[starts-with(., '$/Beta')]"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

当应用于此输入XML时(与您的一样,但添加了额外的非匹配文件):

<root>
  <file>
    <name>file.bat</name>
    <version>111</version>
    <checkedout>No</checkedout>
    <binary>Text</binary>
    <vss_path>$/Code/file.bat</vss_path>
    <original_path>C:\code\file.bat</original_path>
    <action>Labeled &apos;1.2.3.4&apos;</action>
    <date>27/09/2013 09:08:00</date>
    <comment></comment>
    <label>1.2.3.4</label>
    <label_comment></label_comment>
    <user>John</user>
    <shared_links>
      <shared_link>$/Alpha_1</shared_link>
      <shared_link>$/Branches/New_Feature</shared_link>
    </shared_links>
  </file>
  <file>
    <name>file.bat</name>
    <version>111</version>
    <checkedout>No</checkedout>
    <binary>Text</binary>
    <vss_path>$/Code/file.bat</vss_path>
    <original_path>C:\code\file.bat</original_path>
    <action>Labeled &apos;1.2.3.4&apos;</action>
    <date>27/09/2013 09:08:00</date>
    <comment></comment>
    <label>1.2.3.4</label>
    <label_comment></label_comment>
    <user>John</user>
    <shared_links>
      <shared_link>$/Beta_1</shared_link>
      <shared_link>$/Branches/New_Feature</shared_link>
    </shared_links>
  </file>
</root>

生成以下输出XML:

<root>
  <file>
    <name>file.bat</name>
    <vss_path>$/Code/file.bat</vss_path>
    <shared_links>
      <shared_link>$/Beta_1</shared_link>
    </shared_links>
  </file>
</root>