我们正在使用返回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>
来自服务的“常规”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>
答案 0 :(得分:0)
我可能误解了这个问题,但这不仅仅是添加模板规则
的问题<xsl:template match="diffgr:diffgram">[]</xsl:template>
答案 1 :(得分:0)
第一次将XML提供给包含多个Event节点的样式表时,您会发现不需要for-each。
但就主要问题而言 - 我们谈论的空虚有多么?我的意思是,零长度文件不是有效的XML。但是,如果你得到一个没有Event节点的NewDataSet,你应该在那个级别创建一个封闭对象,如果没有Events,你会自动获得一个空对象。有点像:
<xsl:template match="NewDataSet">
{
<xsl:apply-templates/>
}
<xsl:template>
<强>更新强>
看到附加帖子(“常规”XML)后,我看到你正在处理的丑陋的Web服务。真?他们在每个响应中嵌入了模式,即使该响应没有给出数据?啊。
无论如何,我之前建议的变化应该有效。似乎你确信收到的一件事就是diffgram节点。因此,创建一个创建封闭JSON对象的那个。我建议你在你的XSL中添加一个xslns:diffgr声明 - local-name()就像欺骗我一样。
所以,你会按照以下方式做点什么:
<xsl:template match="diffgr:diffgram">
{
<xsl:apply-templates select="NewDataSet/Events"/>
}
</xsl:template>
答案 2 :(得分:-1)
我对如何回答这个问题犹豫不决,因为即使响应包含数据,样式表也不会返回有效的JSON文档。因此,我建议您查看以下内容,并在必要时进行必要的调整。
以下样式表:
XSLT 1.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": ""
}
]
}
这与样式表产生的不完全相同 - 但它确实通过了验证:http://jsonlint.com/
相同样式表在应用于第一个输入XML示例时将返回:
{}
注意:我相信使用<xsl:text>
输出文字文本可以更好地控制空格。