检查转换中的不同根

时间:2011-11-03 20:34:31

标签: c# xml xslt

我有以下xslt表,我想知道是否可以检查xml文件中的某个根?如果是这样,为了转换xml以使用某个模板,需要什么正确的xslt代码?我尝试使用下面的样式表来构建,但是这引发了一个错误,抱怨无效的root。如果我在xml文件中有一个根,我可以从这个样式表中得出结论,我想对它应用一个特定的模板。你们都觉得怎么样?

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="xml" indent="yes"/>

<xsl:template match="/Envelope">
  <xsl:apply-templates select="Payload" />
</xsl:template>

<xsl:template match="/Request1">
    <xsl:apply-templates select="Payload"/>
</xsl:template>

<xsl:template match="/Request2">
  <xsl:apply-templates select="Payload2"/>
</xsl:template>

<xsl:template match="Payload" >
 <soap12:Envelope >
  <soap12:Body>
    <Method1>
      <xdocPayload>
        <xsl:copy>
          <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
      </xdocPayload>
    </Method1>
    </soap12:Body>
  </soap12:Envelope>
</xsl:template>


<xsl:template match="Payload2" >
  <soap12:Envelope>
    <soap12:Body>
      <Method2>
       <xdocPayload>
         <xsl:copy>
          <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
      </xdocPayload>
      </Method2>
   </soap12:Body>
 </soap12:Envelope>
</xsl:template>


</xsl:stylesheet>

c#Code我正在测试:

  XslCompiledTransform xslt = new XslCompiledTransform(true);

  xslt.Load(XmlReader.Create(new StringReader(xsltTransSheet)));

非常感谢任何帮助。

谢谢, DND

2个不同的XML输入文件:

 <Envelope>
     <order>1280</order>
 </Envelope>

或可能是

 <Request1>
    <item>7329HH</item>
 <Request1>

所需的XML输出:

<soap12:Body>
            <Method1>
                <xdocPayload>
                   <Envelope>
                     <order>1280</order>
                   </Envelope>
                </xdocPayload>
             </Method1>
 </soap12:Body>

或XML输出最终将

  <soap12:Body>
            <Method1>
                <xdocPayload>
                   <Request1>
                      <item>7329HH</item>
                   </Request1>
                </xdocPayload>
             </Method1>
  </soap12:Body>

我正在寻找一个或另一个结果,取决于输入xslt的xml。希望这能更彻底地解释它。

1 个答案:

答案 0 :(得分:0)

您在输出中使用了soap12命名空间前缀。您应该在样式表的根目录中声明它,如下所示:

<xsl:stylesheet ... xmlns:soap12="someuri" ...>

如果输入根不能与任何模板匹配,或者输出无效的XML文件,那么样式表也可能实际上不输出任何内容。如果您的XML中某处有PayloadPayload2元素,但其根元素与任何模板都不匹配,则可能就是后者。

您可能需要考虑使用命名模板并调用它们,而不是将apply-templates用于可能与上下文匹配的内容。或者使用模板模式确保您只使用另一个模板。

编辑:看看这个XML ......

<?xml version="1.0" encoding="UTF-8"?>
<test>
    <Payload/>
    <Payload2/>
</test>

将样式表应用于它(带有更正的soap12声明)将产生以下结果:

<?xml version="1.0" encoding="UTF-8"?>
<soap12:Envelope xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
    <soap12:Body>
        <Method1>
            <xdocPayload>
                <Payload/>
            </xdocPayload>
        </Method1>
    </soap12:Body>
</soap12:Envelope>
<soap12:Envelope xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
    <soap12:Body>
        <Method2>
            <xdocPayload>
                <Payload2/>
            </xdocPayload>
        </Method2>
    </soap12:Body>
</soap12:Envelope>

这不是有效的XML,因为有两个根元素,这是不允许的。

这是建议的样式表重写:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope" exclude-result-prefixes="msxsl">

    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="/Envelope" priority="2">
        <soap12:Envelope>
            <xsl:apply-templates select="Payload"/>
        </soap12:Envelope>
    </xsl:template>

    <xsl:template match="/Request1" priority="2">
        <soap12:Envelope>
            <xsl:apply-templates select="Payload"/>
        </soap12:Envelope>
    </xsl:template>

    <xsl:template match="/Request2" priority="2">
        <soap12:Envelope>
            <xsl:apply-templates select="Payload2"/>
        </soap12:Envelope>
    </xsl:template>

    <xsl:template match="/*" priority="1">
        <soap12:Envelope />
    </xsl:template>

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

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

</xsl:stylesheet>

请注意,我没有完整的输入或所需输出的图片,所以不要简单地按照上面的内容,而是根据自己的要求查看它的作用并纠正。

编辑2:好的,在您添加样本后,您更清楚自己想要做什么。您需要简单地调用命名模板,就像我之前建议的那样。这是开始的基础。根据需要进行调整,确保测试各种输入案例。找一个编辑程序,让你快速试用甚至调试XSLT,它会有很大的帮助:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope" exclude-result-prefixes="msxsl">

    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="/Envelope" priority="2">
        <soap12:Envelope>
            <xsl:call-template name="Payload"/>
        </soap12:Envelope>
    </xsl:template>

    <xsl:template match="/Request1" priority="2">
        <soap12:Envelope>
             <xsl:call-template name="Payload"/>
        </soap12:Envelope>
    </xsl:template>

    <xsl:template match="/Request2" priority="2">
        <soap12:Envelope>
             <xsl:call-template name="Payload2"/>
        </soap12:Envelope>
    </xsl:template>

    <xsl:template match="/*" priority="1">
        <soap12:Envelope />
    </xsl:template>

    <xsl:template name="Payload">
            <soap12:Body>
                <Method1>
                    <xdocPayload>
                        <xsl:copy-of select="." />
                    </xdocPayload>
                </Method1>
            </soap12:Body>
    </xsl:template>

    <xsl:template name="Payload2">
            <soap12:Body>
                <Method2>
                    <xdocPayload>
                        <xsl:copy-of select="." />
                    </xdocPayload>
                </Method2>
            </soap12:Body>
    </xsl:template>

</xsl:stylesheet>