Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/13.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
Xml 使用XSLT返回空的有效JSON对象_Xml_Json_Xslt - Fatal编程技术网

Xml 使用XSLT返回空的有效JSON对象

Xml 使用XSLT返回空的有效JSON对象,xml,json,xslt,Xml,Json,Xslt,我们正在使用一个返回XML的web服务,我们正在使用XSLT对日期进行排序,并只将其中的一部分发送到移动客户端。返回给客户机的数据是JSON解析的。 对于给定的参数,服务返回一个空XML,如问题末尾所示 在本例中,我们要做的是找出如何将空的有效JSON对象(即[])返回给客户端。目前,我们无法更改web服务本身中的任何内容。任何想法都会很有帮助 XML: <?xml version="1.0" encoding="utf-8"?> <DataSet xmlns="http://

我们正在使用一个返回XML的web服务,我们正在使用XSLT对日期进行排序,并只将其中的一部分发送到移动客户端。返回给客户机的数据是JSON解析的。 对于给定的参数,服务返回一个空XML,如问题末尾所示

在本例中,我们要做的是找出如何将空的有效JSON对象(即[])返回给客户端。目前,我们无法更改web服务本身中的任何内容。任何想法都会很有帮助

XML:

<?xml version="1.0" encoding="utf-8"?>
<DataSet xmlns="http://tempuri.org/">
  <xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:Locale="">
      <xs:complexType>
        <xs:choice maxOccurs="unbounded">
          <xs:element name="Events">
            <xs:complexType>
              <xs:sequence>
                <xs:element name="Name" type="xs:string" minOccurs="0" />
                <xs:element name="boneId" type="xs:int" minOccurs="0" />
                <xs:element name="nsId" type="xs:int" minOccurs="0" />
                <xs:element name="objId" type="xs:int" minOccurs="0" />
                <xs:element name="fileName" type="xs:string" minOccurs="0" />
                <xs:element name="Date" type="xs:dateTime" minOccurs="0" />
                <xs:element name="ArieId" type="xs:int" minOccurs="0" />
                <xs:element name="EventPlaceName" type="xs:string" minOccurs="0" />
                <xs:element name="City" type="xs:int" minOccurs="0" />
                <xs:element name="PlaceFileName" type="xs:string" minOccurs="0" />
                <xs:element name="PlaceBoneId" type="xs:int" minOccurs="0" />
                <xs:element name="PlaceNsId" type="xs:int" minOccurs="0" />
                <xs:element name="PlaceObjId" type="xs:int" minOccurs="0" />
                <xs:element name="TourName" type="xs:string" minOccurs="0" />
                <xs:element name="TimeStart" type="xs:string" minOccurs="0" />
                <xs:element name="TimeEnd" type="xs:string" minOccurs="0" />
                <xs:element name="Genre" type="xs:int" minOccurs="0" />
                <xs:element name="Genre_Name" type="xs:string" minOccurs="0" />
              </xs:sequence>
            </xs:complexType>
          </xs:element>
        </xs:choice>
      </xs:complexType>
    </xs:element>
  </xs:schema>
  <diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1" />
</DataSet>

XSLT:

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:h="http://www.w3.org/1999/xhtml">
    <xsl:output method="text"/>
    <xsl:template match="Events">
        {
            'Items': [
                <xsl:for-each select="//Events">                                
                    {

                        'Name':             '<xsl:value-of select="Name"/>',
                        'Date':             '<xsl:value-of select="Date"/>',
                        'PlaceName':        '<xsl:value-of select="EventPlaceName"/>',
                        'boneId':           '<xsl:value-of select="boneId"/>',
                        'objId':            '<xsl:value-of select="objId"/>',
                        'PlaceNsId':        '<xsl:value-of select="PlaceNsId"/>',
                        'PlaceObjId':       '<xsl:value-of select="PlaceObjId"/>',
                        'StartPoint':       '<xsl:value-of select="StartPoint"/>',
                        'Description':      '<xsl:value-of select="Description"/>',
                        'Telephone':        '<xsl:value-of select="Telephone"/>'
                    },
                </xsl:for-each>
            ]       
        }
    </xsl:template>

</xsl:stylesheet>

{
“项目”:[
{
“姓名”:“,
“日期”:“,
“地名”:“,
“boneId”:“,
“对象”:“,
“PlaceNsId”:“,
“PlaceObjId”:“,
“起点”:“,
“描述”:“,
“电话”:”
},
]       
}
来自服务的“常规”XML响应:

<?xml version="1.0" encoding="utf-8"?>
<DataSet xmlns="http://tempuri.org/">
  <xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:Locale="">
      <xs:complexType>
        <xs:choice maxOccurs="unbounded">
          <xs:element name="Events">
            <xs:complexType>
              <xs:sequence>
                <xs:element name="Name" type="xs:string" minOccurs="0" />
                <xs:element name="boneId" type="xs:int" minOccurs="0" />
                <xs:element name="nsId" type="xs:int" minOccurs="0" />
                <xs:element name="objId" type="xs:int" minOccurs="0" />
                <xs:element name="fileName" type="xs:string" minOccurs="0" />
                <xs:element name="Date" type="xs:dateTime" minOccurs="0" />
                <xs:element name="ArieId" type="xs:int" minOccurs="0" />
                <xs:element name="EventPlaceName" type="xs:string" minOccurs="0" />
                <xs:element name="City" type="xs:int" minOccurs="0" />
                <xs:element name="PlaceFileName" type="xs:string" minOccurs="0" />
                <xs:element name="PlaceBoneId" type="xs:int" minOccurs="0" />
                <xs:element name="PlaceNsId" type="xs:int" minOccurs="0" />
                <xs:element name="PlaceObjId" type="xs:int" minOccurs="0" />
                <xs:element name="TourName" type="xs:string" minOccurs="0" />
                <xs:element name="TimeStart" type="xs:string" minOccurs="0" />
                <xs:element name="TimeEnd" type="xs:string" minOccurs="0" />
                <xs:element name="Genre" type="xs:int" minOccurs="0" />
                <xs:element name="Genre_Name" type="xs:string" minOccurs="0" />
              </xs:sequence>
            </xs:complexType>
          </xs:element>
        </xs:choice>
      </xs:complexType>
    </xs:element>
  </xs:schema>
  <diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
    <NewDataSet xmlns="">
      <Events diffgr:id="Events1" msdata:rowOrder="0">
        <Name>Name</Name>
        <boneId>1855</boneId>
        <nsId>305</nsId>
        <objId>28</objId>
        <fileName>tours_item_show.aspx</fileName>
        <ArieId>1</ArieId>
        <EventPlaceName>Place name</EventPlaceName>
        <City>392</City>
        <PlaceFileName>show_item_place.aspx</PlaceFileName>
        <PlaceBoneId>1563</PlaceBoneId>
        <PlaceNsId>201</PlaceNsId>
        <PlaceObjId>2574</PlaceObjId>
        <TourName>Tour name</TourName>
        <Genre>18</Genre>
        <Genre_Name>Group tours</Genre_Name>
      </Events>
    </NewDataSet>
  </diffgr:diffgram>
</DataSet>

名称
1855
305
28
tours\u item\u show.aspx
1.
地名
392
show_item_place.aspx
1563
201
2574
旅游名称
18
团体旅游

我可能误解了这个问题,但这不只是添加模板规则的问题吗

<xsl:template match="diffgr:diffgram">[]</xsl:template>
[]

第一次将XML提供给包含多个事件节点的样式表时,您会意识到不需要为其中的每个节点都指定一个

但就主要问题而言——我们谈论的有多空洞?我的意思是,零长度文件不是有效的XML。但是,如果您获得的是一个没有事件节点的NewDataSet,那么您应该在该级别创建封闭对象,如果没有事件,您将自动获得一个空对象。大致如下:

<xsl:template match="NewDataSet">
    {
    <xsl:apply-templates/>
    }
<xsl:template>

{
}
更新:

在看到附加的帖子(“常规”XML)之后,我看到了您正在处理的是一个多么丑陋的web服务。真正地他们在每个响应中嵌入模式,即使该响应没有提供任何数据?啊

不管怎样,我以前建议的一个变化应该是可行的。看起来,您可以确保接收到的一件事情是diffgram节点。因此,让它成为创建封闭JSON对象的对象。我建议您在XSL--local-name()中添加一个xslns:diffgr声明,这让我感觉像是在作弊

因此,您将按照以下思路进行操作:

<xsl:template match="diffgr:diffgram">
    {
    <xsl:apply-templates select="NewDataSet/Events"/>
    }
</xsl:template>

{
}

我不知道如何准确回答这个问题,因为即使响应包含数据,样式表也不会返回有效的JSON文档。因此,我建议您查看以下内容,并在必要时进行必要的调整

以下样式表:

XSLT1.0

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/*">
{<xsl:apply-templates select="*/NewDataSet"/>}
</xsl:template> 

<xsl:template match="NewDataSet">
"Items":[<xsl:apply-templates select="Events"/>]
</xsl:template> 

<xsl:template match="Events">
    {
        "Name":             "<xsl:value-of select="Name"/>",
        "Date":             "<xsl:value-of select="Date"/>",
        "PlaceName":        "<xsl:value-of select="EventPlaceName"/>",
        "boneId":           "<xsl:value-of select="boneId"/>",
        "objId":            "<xsl:value-of select="objId"/>",
        "PlaceNsId":        "<xsl:value-of select="PlaceNsId"/>",
        "PlaceObjId":       "<xsl:value-of select="PlaceObjId"/>",
        "StartPoint":       "<xsl:value-of select="StartPoint"/>",
        "Description":      "<xsl:value-of select="Description"/>",
        "Telephone":        "<xsl:value-of select="Telephone"/>"
    }
</xsl:template> 

</xsl:stylesheet>
这与样式表生成的内容并不完全相同,但它确实通过了此处的验证:

相同的样式表应用于第一个输入XML示例时将返回:

{
"Items":[
    {
        "Name":             "Name",
        "Date":             "",
        "PlaceName":        "Place name",
        "boneId":           "1855",
        "objId":            "28",
        "PlaceNsId":        "201",
        "PlaceObjId":       "2574",
        "StartPoint":       "",
        "Description":      "",
        "Telephone":        ""
    }
]
}
{}

注意:我相信使用
输出文本可以更好地控制空白。

我想您已经理解了这个问题。然而,上述规则并不奏效。其思想是为有数据的案例(已经完成)和没有数据的案例提供一个模板规则,并且能够对这两种案例使用相同的XSLT。您建议的规则在这两种情况下都会失败,并出现以下错误:“名称空间前缀'diffgr'未声明。”对不起,我假设您知道足够多的XSLT,知道如果在匹配模式中使用名称空间前缀,则必须声明它。“对于给定参数,服务返回一个空XML-如问题末尾所示。”我看不出你在哪里表现出来。这一点非常重要,因为不存在空XML。If必须至少有一个根元素,否则它根本不是XML。顺便说一句,我认为您错误地发布了XSD,而不是实际的XML响应示例。因此,请编辑我们的问题,并提供两个XML输入示例:“常规”输入和“空”输入。我在原来的问题上加了一个“常规”。