Xml 使用XSLT返回空的有效JSON对象
我们正在使用一个返回XML的web服务,我们正在使用XSLT对日期进行排序,并只将其中的一部分发送到移动客户端。返回给客户机的数据是JSON解析的。 对于给定的参数,服务返回一个空XML,如问题末尾所示 在本例中,我们要做的是找出如何将空的有效JSON对象(即[])返回给客户端。目前,我们无法更改web服务本身中的任何内容。任何想法都会很有帮助 XML: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 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输入示例:“常规”输入和“空”输入。我在原来的问题上加了一个“常规”。