Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/jenkins/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么在SOAP头中包含某些内容会阻止它与XSLT模板匹配?_C#_Xml_Xslt_Soap - Fatal编程技术网

C# 为什么在SOAP头中包含某些内容会阻止它与XSLT模板匹配?

C# 为什么在SOAP头中包含某些内容会阻止它与XSLT模板匹配?,c#,xml,xslt,soap,C#,Xml,Xslt,Soap,我有一个类似这样的SOAP(1.1)信封: <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:l3="http://tempuri.org/l3"> <soapenv:Header> <l3:requestType>Valid</l3:requestType> </soapenv:Header> <

我有一个类似这样的SOAP(1.1)信封:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:l3="http://tempuri.org/l3">
  <soapenv:Header>
    <l3:requestType>Valid</l3:requestType>
  </soapenv:Header>
  <soapenv:Body>
    <l3:xyzRequest xsi:schemaLocation="http://tempuri.org/l3 lds.xsd " requestId="7291655" functionalId="1645885" appChannel="XYZ" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <workpackageId>126381</workpackageId>
      ...
    </l3:xyzRequest>
  </soapenv:Body>
</soapenv:Envelope>
<xsl:template match="soapenv:Envelope/soapenv:Body/l3:xyzRequest">
  ...
</xsl:template>

有效的
126381
...
XSLT模板如下所示:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:l3="http://tempuri.org/l3">
  <soapenv:Header>
    <l3:requestType>Valid</l3:requestType>
  </soapenv:Header>
  <soapenv:Body>
    <l3:xyzRequest xsi:schemaLocation="http://tempuri.org/l3 lds.xsd " requestId="7291655" functionalId="1645885" appChannel="XYZ" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <workpackageId>126381</workpackageId>
      ...
    </l3:xyzRequest>
  </soapenv:Body>
</soapenv:Envelope>
<xsl:template match="soapenv:Envelope/soapenv:Body/l3:xyzRequest">
  ...
</xsl:template>

...
我正在Visual Studio 2013(.NET Framework 4.5.1)中使用C#。以下是转换代码:

XslCompiledTransform xslt = new XslCompiledTransform(false);
StringBuilder sb = new StringBuilder();

xslt.Load(@"<XSLTPath>");

using (XmlWriter xw = XmlWriter.Create(sb, xslt.OutputSettings))
{
    xslt.Transform(XML.CreateReader(), xw);
}
xslcomiledtransform xslt=新的xslcomiledtransform(false);
StringBuilder sb=新的StringBuilder();
Load(@“”);
使用(xmlwriterxw=XmlWriter.Create(sb,xslt.OutputSettings))
{
Transform(XML.CreateReader(),xw);
}
当我运行转换时,模板是不匹配的,但是如果我从SOAP头中删除
元素(不做任何其他更改),它可以正常工作。有人知道为什么吗

编辑:

根据提供更多代码的请求,以下是重现问题的最小示例:

using System;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Xsl;

namespace Project1
{
    class Program
    {
        static void Main()
        {
            XDocument XSL = XDocument.Parse("<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:l3=\"http://tempuri.org/l3\" version=\"1.0\">" +
                    "<xsl:output method=\"xml\" />" +
                    "<xsl:template match=\"soapenv:Envelope/soapenv:Body/l3:xyzRequest\">" +
                        "<Test><xsl:value-of select=\"workpackageId\" /></Test>" +
                    "</xsl:template>" +
                "</xsl:stylesheet>");
            XDocument XML = XDocument.Parse("<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:l3=\"http://tempuri.org/l3\">" +
                    "<soapenv:Header>" +
                        "<l3:requestType>Valid</l3:requestType>" +
                    "</soapenv:Header>" +
                    "<soapenv:Body>" +
                        "<l3:xyzRequest xsi:schemaLocation=\"http://tempuri.org/l3 lds.xsd \" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" +
                            "<workpackageId>126381</workpackageId>" +
                        "</l3:xyzRequest>" +
                    "</soapenv:Body>" +
                "</soapenv:Envelope>");
            XslCompiledTransform xslt = new XslCompiledTransform(false);
            StringBuilder sb = new StringBuilder();

            xslt.Load(XSL.CreateReader());

            using (XmlWriter xw = XmlWriter.Create(sb, xslt.OutputSettings))
            {
                xslt.Transform(XML.CreateReader(), xw);
            }

            Console.WriteLine(sb.ToString());
            Console.ReadLine();
        }
    }
}
使用系统;
使用系统文本;
使用System.Xml;
使用System.Xml.Linq;
使用System.Xml.Xsl;
命名空间项目1
{
班级计划
{
静态void Main()
{
XDocument XSL=XDocument.Parse(“”)+
"" +
"" +
"" +
"" +
"");
XDocument XML=XDocument.Parse(“”)+
"" +
“有效”+
"" +
"" +
"" +
"126381" +
"" +
"" +
"");
XslCompiledTransform xslt=新XslCompiledTransform(false);
StringBuilder sb=新的StringBuilder();
Load(XSL.CreateReader());
使用(xmlwriterxw=XmlWriter.Create(sb,xslt.OutputSettings))
{
Transform(XML.CreateReader(),xw);
}
Console.WriteLine(sb.ToString());
Console.ReadLine();
}
}
}
如果运行该命令,模板将不匹配,并且您将获得返回所有节点值的默认行为:
Valid126381
;但是,如果您注释掉第21行(
“Valid”+
),模板将匹配,您将得到预期结果:
126381

编辑2:


哎呀,我刚刚注意到我上面发布的第一个结果不是默认行为,但它不是格式良好的XML,这让我很反感。很抱歉,复制和粘贴时应该仔细看看!我想现在的问题是:当一个元素包含在SOAP头中时,为什么返回它的值,即使它不是来自XSLT模板?

最明显的可能原因是,用于匹配输入中l3:xyzRequest元素的模板可能不会产生任何结果:

  • 输入可能没有任何l3:xyzRequest元素。如果您显示的输入片段是正确的,这不是您的问题

  • 模板上的匹配模式可能与预期的元素不匹配;这可能是由拼写错误的名称、绑定命名空间前缀的错误或XPath表达式公式中的问题造成的。乍一看,这似乎不是你的问题

  • 样式表可能永远不会要求处理器处理该元素。(更具体地说:可能没有xsl:apply-templates指令包含它选择的节点中的l3:xyzRequest元素。)如果没有完整查看样式表,就无法确认这是问题的原因,但也不能排除

您可以说,如果从输入中删除不同的元素会导致转换“正常工作”。我猜这意味着在这种情况下,模板确实会从l3:xyzRequest元素生成输出。这表明基于其他元素的存在或不存在(或值)的某些条件正在影响样式表处理

我的建议是开始减少样式表,直到您拥有尽可能最小的样式表,该样式表显示您试图更改的行为(“当l3:requestType元素丢失时工作正常,当它出现时中断”)。当你把它减少到20行左右时,答案要么是显而易见的,要么对于一些堆栈溢出阅读器来说相对容易找到

[附录]一旦将代码中的XML和XSLT从C#中分离出来,它就混合在一起了,您就有了这个XML实例:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
                  xmlns:l3="http://tempuri.org/l3">
  <soapenv:Header>
    <l3:requestType>Valid</l3:requestType>
  </soapenv:Header>
  <soapenv:Body>
    <l3:xyzRequest xsi:schemaLocation="http://tempuri.org/l3 lds.xsd " 
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <workpackageId>126381</workpackageId>
    </l3:xyzRequest>
  </soapenv:Body>
</soapenv:Envelope>

有效的
126381
要使用此XSLT进行处理,请执行以下操作:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                xmlns:l3="http://tempuri.org/l3" version="1.0">
  <xsl:output method="xml" />
  <xsl:template
      match="soapenv:Envelope/soapenv:Body/l3:xyzRequest">
    <Test><xsl:value-of select="workpackageId"/></Test>
  </xsl:template>
</xsl:stylesheet>

在此XML上运行此样式表将生成以下输出:

<?xml version="1.0"?>


    Valid


    <Test xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:l3="http://tempuri.org/l3">126381</Test>

有效的
126381
我不清楚你为什么认为模板不匹配


字符串“Valid”出现在输出中,因为您没有覆盖内置的默认模板(通过在子元素上循环来处理元素,通过将文本节点复制到输出来处理文本节点)。

请向我们显示两行以上的XSLT。你给我们看的部分不是问题所在。谢谢你提供的信息,我很抱歉没有说得更清楚!XSLT已经被削减到最低限度,但从我发布的内容来看,这并不明显。我已经用一个完整的代码示例编辑了我的文章,我希望这将使问题易于重现。再次感谢您的帮助!谢谢你的解释。我没有意识到它在一个元素的所有子元素上都是递归的。