传递XML片段注入XSLT作为参数(Passing Xml Snippet into xslt as

2019-10-16 15:53发布

我试图解决目前的问题是生成的两个XML文件,通过XSLT异同的比较。

例如,第一个XML文件的样子

<?xml version="1.0" encoding="utf-8" ?>
<Stats Date="2011-01-01">
  <Player Rank="1">
    <GP>39</GP>
    <G>32</G>
    <A>33</A>
    <PlusMinus>20</PlusMinus>
    <PIM>29</PIM>
    <PP>10</PP>
    <SH>1</SH>
    <GW>3</GW>
    <Shots>0</Shots>
    <ShotPctg>154</ShotPctg>
    <TOIPerGame>20.8</TOIPerGame>
    <ShiftsPerGame>21:54</ShiftsPerGame>
    <FOWinPctg>22.6</FOWinPctg>
  </Player>
</Stats>

第二个文件看起来像

<?xml version="1.0" encoding="utf-8" ?>
<Stats Date="2011-01-01">
  <Player Rank="2">
    <Name>John Smith</Name>
    <Team>NY</Team>
    <Pos>D</Pos>
    <GP>38</GP>
    <G>32</G>
    <A>33</A>
    <PlusMinus>15</PlusMinus>
    <PIM>29</PIM>
    <PP>10</PP>
    <SH>1</SH>
    <GW>4</GW>
    <Shots>0</Shots>
    <ShotPctg>158</ShotPctg>
    <TOIPerGame>20.8</TOIPerGame>
    <ShiftsPerGame>21:54</ShiftsPerGame>
    <FOWinPctg>22.6</FOWinPctg>
  </Player>
</Stats>

当我嵌入第二个文件到XSLT文件输出工作按预期:

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

  <xsl:param name="vrtfDoc2">
    <Stats Date="2011-01-01">
      <Player Rank="2">
        <Name>John Smith</Name>
        <Team>NY</Team>
        <Pos>D</Pos>
        <GP>38</GP>
        <G>32</G>
        <A>33</A>
        <PlusMinus>15</PlusMinus>
        <PIM>29</PIM>
        <PP>10</PP>
        <SH>1</SH>
        <GW>4</GW>
        <Shots>0</Shots>
        <ShotPctg>158</ShotPctg>
        <TOIPerGame>20.8</TOIPerGame>
        <ShiftsPerGame>21:54</ShiftsPerGame>
        <FOWinPctg>22.6</FOWinPctg>
      </Player>
    </Stats>
  </xsl:param>

  <xsl:variable name="vDoc2" select=
  "document('')/*/xsl:param[@name='vrtfDoc2']/*"/>

  <xsl:template match="node()|@*" name="identity">
    <xsl:param name="pDoc2"/>
    <xsl:copy>
      <xsl:apply-templates select="node()|@*">
        <xsl:with-param name="pDoc2" select="$pDoc2"/>
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="/">
    <xsl:apply-templates select="*">
      <xsl:with-param name="pDoc2" select="$vDoc2"/>
    </xsl:apply-templates>

    -----------------------

    <xsl:apply-templates select="$vDoc2">
      <xsl:with-param name="pDoc2" select="/*"/>
    </xsl:apply-templates>
  </xsl:template>

  <xsl:template match="Player/*">
    <xsl:param name="pDoc2"/>
    <xsl:if test=
   "not(. = $pDoc2/*/*[name()=name(current())])">
      <xsl:call-template name="identity"/>
    </xsl:if>
  </xsl:template>

  <xsl:template match="Name|Team|Pos" priority="20"/>
</xsl:stylesheet>

使用下面的C#代码时:

private string Transform(string xml, string xml2, string xsl) {
            StringWriter writer = new StringWriter();
            XslCompiledTransform t = new XslCompiledTransform(true);
            XsltSettings settings = new XsltSettings(true, false);
            XmlTextReader xmlReader = new XmlTextReader(xml);

            XmlTextReader xslReader = new XmlTextReader(xsl);
            t.Load(xslReader, settings, null);

            t.Transform(xmlReader, null, writer);
            return writer.ToString();
        }

当我从XSLT删除嵌入式xml

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

  <xsl:param name="vrtfDoc2" />

  <xsl:variable name="vDoc2" select=
  "document('')/*/xsl:param[@name='vrtfDoc2']/*"/>

  <xsl:template match="node()|@*" name="identity">
    <xsl:param name="pDoc2"/>
    <xsl:copy>
      <xsl:apply-templates select="node()|@*">
        <xsl:with-param name="pDoc2" select="$pDoc2"/>
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="/">
    <xsl:apply-templates select="*">
      <xsl:with-param name="pDoc2" select="$vDoc2"/>
    </xsl:apply-templates>

    -----------------------

    <xsl:apply-templates select="$vDoc2">
      <xsl:with-param name="pDoc2" select="/*"/>
    </xsl:apply-templates>
  </xsl:template>

  <xsl:template match="Player/*">
    <xsl:param name="pDoc2"/>
    <xsl:if test=
   "not(. = $pDoc2/*/*[name()=name(current())])">
      <xsl:call-template name="identity"/>
    </xsl:if>
  </xsl:template>

  <xsl:template match="Name|Team|Pos" priority="20"/>
</xsl:stylesheet>

变化的C#方法

private string Transform(string xml, string xml2, string xsl) {
            StringWriter writer = new StringWriter();
            XslCompiledTransform t = new XslCompiledTransform(true);
            XsltSettings settings = new XsltSettings(true, false);
            XmlTextReader xmlReader = new XmlTextReader(xml);

            XmlDocument doc1 = new XmlDocument();
            // populate as needed e.g.
            doc1.Load(xml2);

            XmlTextReader xslReader = new XmlTextReader(xsl);
            t.Load(xslReader, settings, null);

            //Pass parameter value to xslt from code
            XsltArgumentList argumentList = new XsltArgumentList();
            argumentList.AddParam("vrtfDoc2", "", doc1);
            t.Transform(xmlReader, argumentList, writer);
            return writer.ToString();
        }

我从一个空白输出的变换,对我的生活我不明白为什么。 我使用调试器通过两个版本加强和参数值看起来相同的两个occassions但当参数传递版本打下面的代码片段在XSLT转换不会发生:

<xsl:apply-templates select="$vDoc2">
      <xsl:with-param name="pDoc2" select="/*"/>
    </xsl:apply-templates>
  </xsl:template>

  <xsl:template match="Player/*">
    <xsl:param name="pDoc2"/>
    <xsl:if test=
   "not(. = $pDoc2/*/*[name()=name(current())])">
      <xsl:call-template name="identity"/>
    </xsl:if>
  </xsl:template>

任何帮助或建议将非常appeciated。

Answer 1:

问题是,在这样的代码

  <xsl:param name="vrtfDoc2" />    

  <xsl:variable name="vDoc2" select=   
     "document('')/*/xsl:param[@name='vrtfDoc2']/*"/>

该分析包含XSLT样式表文件,定位格洛巴; xsl:param具有name属性以字符串值"vrtfDoc2" ,并选择该的子元素xsl:param -但它一直没有孩子,因此价值$vDoc2是空节点集。

解决方案

只需使用

<xsl:variable name="vDoc2" select="$vrtfDoc2/*"/>

注释关于命名

作为当前的名字是混乱和误导请重命名参数:

  1. 使用开始名字p参数和名称以v变量。

  2. 像的名称vrtfDoc2通常意味着: 这个变量包含RTF(和通常需要的XXX:节点集()函数,以便从它产生一个正则树将被施加到它)。 然而,这是不是你的情况的情况。

因此,参数名称,如: pDoc2更精确有效的信息。



文章来源: Passing Xml Snippet into xslt as parameter
标签: c# xml xslt