c# -//<node> 没有给出所有匹配的节点

标签 c# xslt

给定以下 XML:

<root>
  <StepFusionSet name="SF1">
      <StepFusionSet name="SF2">
      </StepFusionSet>
  </StepFusionSet>
  <StepFusionSet name="SF10">
  </StepFusionSet>
</root>

以下 C# 代码:

        XPathDocument doc = new XPathDocument("input.xml");
        var nav = doc.CreateNavigator();

        var item = nav.Select("//StepFusionSet[@name]");
        while (item.MoveNext())
        {
            Debug.WriteLine(item.Current.GetAttribute("name", item.Current.NamespaceURI));
        }

给我输出:

SF1
SF2
SF10

但是下面的 XSLT 文件:

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

  <xsl:template match="//StepFusionSet">
    <xsl:call-template name="a"/>
  </xsl:template>

  <xsl:template name="a">
      <xsl:apply-templates select="@name"/>
  </xsl:template>
</xsl:stylesheet>

(由 C# 代码调用:)

        XslTransform xslt = new XslTransform();
        xslt.Load("transform.xslt");
        XPathDocument doc = new XPathDocument("input.xml");
        MemoryStream ms = new MemoryStream();

        xslt.Transform(doc, null, ms);

给我输出:

SF1
SF10

我在我的 XSLT 文件中做错了什么?

最佳答案

考虑您的第一个模板……

<xsl:template match="//StepFusionSet">

...适用于您的 SF1和(嵌套)SF2元素:

<StepFusionSet name="SF1">
  <StepFusionSet name="SF2">
  </StepFusionSet>
</StepFusionSet>

模板匹配你的外层 SF1元素;但是,然后需要将其重新应用于匹配元素的子元素以匹配您的内部 SF2 .

这可以通过嵌入递归 <xsl:apply-templates/> 来实现在你的第二个模板定义中:

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

  <xsl:template match="//StepFusionSet">
    <xsl:call-template name="a"/>
  </xsl:template>

  <xsl:template name="a">
    <xsl:apply-templates select="@name"/>
    <xsl:apply-templates/>
  </xsl:template>

</xsl:stylesheet>

或者,您可以使用 <xsl:for-each>元素来选择你所有的 <StepFusionSet>元素(包括嵌套元素,例如 SF2 ):

<?xml version="1.0" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
  <xsl:output method="xml" indent="yes"/>
  <xsl:template match="/">
    <xsl:for-each select="//StepFusionSet">
      <xsl:value-of select="@name"/>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

关于c# -//<node> 没有给出所有匹配的节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8946691/

相关文章:

javascript - 根据 xsl :value-of 有条件地显示 2 个字符中的 1 个

java - Saxon XSLT 和 NodeList 作为参数

c# - 在线程池线程的 Windows Phone 7 上调整图像大小?

c# - 机器人框架 V4 : Question about Input forms cards

c# - 当服务器关闭 keep-alive http 连接时检测或避免客户端 CommunicationException

xslt 模式匹配转换

c# - 如何在 WPF 中将自定义对象绑定(bind)到列表框

c# - ASP.NET 动态表单生成和提交

xslt - 如何使用 XSLT 转换来转换 Soap 对象数据

html - 如果您用 HTML 编写日历,您会使用 Table 标签还是 Div 标签?