每当我尝试将xml转换为json时,几乎没有条件按预期工作。
e.g。
XML
<ns1:OTA_AirSeatMapRS
xmlns:ns1="http://www.opentravel.org/OTA/2003/05"
xmlns="http://www.opentravel.org/OTA/2003/05"
xmlns:fo="http://xml.amadeus.com/SMPRES_97_1_IA"
xmlns:helper="com.openjaw.rules.XSLHelper" Version="1.0" >
<ns1:Success />
<ns1:SeatMapResponses>
<ns1:SeatMapResponse>
<ns1:SeatMapDetails MaxRow="A|C|D|E|F|G|H|K" OverwingEnd="28" OverwingStart="11" SpaceAfter="C|G">
<ns1:CabinClass CabinType="N" EndingRow="44" Name="F" StartingRow="11" cabinLocation="M">
<ns1:AirRows>
<ns1:AirRow MaxNumberOfSeats="6" RowNumber="11">
<ns1:AirSeats>
<ns1:AirSeat SeatAvailability="" SeatCharacteristics="I" SeatNumber="C" />
<ns1:AirSeat SeatAvailability="" SeatCharacteristics="8" SeatNumber="D" />
<ns1:AirSeat SeatAvailability="" SeatCharacteristics="8" SeatNumber="E" />
<ns1:AirSeat SeatAvailability="" SeatCharacteristics="8" SeatNumber="F" />
<ns1:AirSeat SeatAvailability="" SeatCharacteristics="8" SeatNumber="G" />
<ns1:AirSeat SeatAvailability="" SeatCharacteristics="I" SeatNumber="H" />
</ns1:AirSeats>
<ns1:AirRowCharacteristics />
</ns1:AirRow>
<ns1:AirRow MaxNumberOfSeats="1" RowNumber="12">
<ns1:AirSeats>
<ns1:AirSeat SeatAvailability="" SeatCharacteristics="I" SeatNumber="F" />
</ns1:AirSeats>
<ns1:AirRowCharacteristics />
</ns1:AirRow>
<ns1:AirRow MaxNumberOfSeats="0" RowNumber="13">
<ns1:AirSeats />
<ns1:AirRowCharacteristics>Z</ns1:AirRowCharacteristics>
</ns1:AirRow>
<ns1:AirRow MaxNumberOfSeats="0" RowNumber="14">
<ns1:AirSeats />
<ns1:AirRowCharacteristics />
</ns1:AirRow>
<ns1:AirRow MaxNumberOfSeats="3" RowNumber="15">
<ns1:AirSeats>
<ns1:AirSeat SeatAvailability="O" SeatCharacteristics="" SeatNumber="A" />
<ns1:AirSeat SeatAvailability="O" SeatCharacteristics="" SeatNumber="C" />
<ns1:AirSeat SeatAvailability="O" SeatCharacteristics="" SeatNumber="D" />
</ns1:AirSeats>
<ns1:AirRowCharacteristics />
</ns1:AirRow>
</ns1:AirRows>
</ns1:CabinClass>
<
/ns1:SeatMapDetails>
</ns1:SeatMapResponse>
</ns1:SeatMapResponses>
<ns1:cabinLocations>
<ns1:cabinLocation Characteristic="L" Description="Lowerdeck" />
<ns1:cabinLocation Characteristic="M" Description="Maindeck" />
<ns1:cabinLocation Characteristic="U" Description="Upperdeck" />
</ns1:cabinLocations>
</ns1:OTA_AirSeatMapRS>
XSL是:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns1="http://www.opentravel.org/OTA/2003/05"
xmlns:ota="http://www.opentravel.org/OTA/2003/05"
xmlns="http://www.opentravel.org/OTA/2003/05" xmlns:math="http://exslt.org/math"
xmlns:str="http://exslt.org/strings" extension-element-prefixes="str">
<xsl:template match="/">
"seatLayout" : {
<xsl:for-each select="//ns1:cabinLocations/ns1:cabinLocation">
"<xsl:value-of select="@Description"/>" :
{
<xsl:variable name="deck" select="@Characteristic"/>
<xsl:if test="//ns1:CabinClass[@cabinLocation=$deck]">
<xsl:variable name="rowsInDeck" select="//ns1:CabinClass[@cabinLocation=$deck]/../@MaxRow"/>
"equipmentInfo":{
"columns":"<xsl:value-of select="$rowsInDeck"/>",
"columnSpaceAfter":"<xsl:value-of select="//ns1:CabinClass[@cabinLocation=$deck]/../@SpaceAfter"/>",
"wingsStart":"<xsl:value-of select="math:lowest(//ns1:SeatMapDetails[@OverwingStart!='']/ns1:CabinClass[@cabinLocation=$deck]/../@OverwingStart)"/>",
"wingsEnd":"<xsl:value-of select="math:highest(//ns1:SeatMapDetails[@OverwingEnd!='']/ns1:CabinClass[@cabinLocation=$deck]/../@OverwingEnd)"/>",
"cabinName":"<xsl:value-of select="//ns1:CabinClass[@cabinLocation=$deck]/@Name"/>",
"cabinType":"<xsl:value-of select="//ns1:CabinClass[@cabinLocation=$deck]/@CabinType"/>",
"cabinStart":"<xsl:value-of select="math:lowest(//ns1:CabinClass[@cabinLocation=$deck]/@StartingRow)"/>",
"cabinEnd":"<xsl:value-of select="math:highest(//ns1:CabinClass[@cabinLocation=$deck]/@EndingRow)"/>"
}
"rowInfo":{
<xsl:for-each select="//ns1:CabinClass[@cabinLocation=$deck]/ns1:AirRows/ns1:AirRow">
<xsl:variable name="rowNumber" select="@RowNumber"/>
<xsl:variable name="rowCharacteristic" select="//ns1:CabinClass[@cabinLocation=$deck]/ns1:AirRows/ns1:AirRow[@RowNumber=$rowNumber]/ns1:AirRowCharacteristics"/>
"<xsl:value-of select="$rowNumber"/>:{
"rchar":"<xsl:value-of select="$rowCharacteristic" />
"rseats":[
<xsl:for-each select="str:tokenize($rowsInDeck, '|')">
<xsl:variable name="pos" select="position()"/>
<xsl:variable name="seatNumber" select="str:tokenize($rowsInDeck, '|')[position()=$pos]"/>
{
<xsl:value-of select="$deck"/>##<xsl:value-of select="$rowNumber"/>##<xsl:value-of select="$seatNumber"/>
<xsl:if test="boolean(//ns1:CabinClass[@cabinLocation=$deck]/ns1:AirRows/ns1:AirRow[@RowNumber=$rowNumber]/ns1:AirSeats/ns1:AirSeat[@SeatNumber=$seatNumber])">
"available"
</xsl:if>
<xsl:if test="not(boolean(//ns1:CabinClass[@cabinLocation=$deck]/ns1:AirRows/ns1:AirRow[@RowNumber=$rowNumber]/ns1:AirSeats/ns1:AirSeat[@SeatNumber=$seatNumber]))">
"NOT available"
</xsl:if>
}
</xsl:for-each>
]
}
<xsl:if test="position()!=last()">,</xsl:if>
</xsl:for-each>
}
</xsl:if>
}
<xsl:if test="position()!=last()">,</xsl:if>
</xsl:for-each>
}
</xsl:template>
</xsl:stylesheet>
此处如果对于一系列deck-&gt; rowNumber-&gt; seatNumber存在,那么它应该打印可用的其他不可用。 但条件是每次都是假的。
Output :
<?xml version="1.0" encoding="UTF-8"?>
"seatLayout" : {
"Lowerdeck" :
{
}
,
"Maindeck" :
{
"equipmentInfo":{
"columns":"A|C|D|E|F|G|H|K",
"columnSpaceAfter":"C|G",
"wingsStart":"11",
"wingsEnd":"28",
"cabinName":"F",
"cabinType":"N",
"cabinStart":"11",
"cabinEnd":"44"
}
"rowInfo":{
"11:{
"rchar":"
"rseats":[
{
M##11##A
"NOT available"
}
{
M##11##C
"NOT available"
}
{
M##11##D
"NOT available"
}
{
M##11##E
"NOT available"
}
{
M##11##F
"NOT available"
}
{
M##11##G
"NOT available"
}
{
M##11##H
"NOT available"
}
{
M##11##K
"NOT available"
}
]
}
,
"12:{
"rchar":"
"rseats":[
{
M##12##A
"NOT available"
}
{
M##12##C
"NOT available"
}
{
M##12##D
"NOT available"
}
{
M##12##E
"NOT available"
}
{
M##12##F
"NOT available"
}
{
M##12##G
"NOT available"
}
{
M##12##H
"NOT available"
}
{
M##12##K
"NOT available"
}
]
}
,
"13:{
"rchar":"Z
"rseats":[
{
M##13##A
"NOT available"
}
{
M##13##C
"NOT available"
}
{
M##13##D
"NOT available"
}
{
M##13##E
"NOT available"
}
{
M##13##F
"NOT available"
}
{
M##13##G
"NOT available"
}
{
M##13##H
"NOT available"
}
{
M##13##K
"NOT available"
}
]
}
,
"14:{
"rchar":"
"rseats":[
{
M##14##A
"NOT available"
}
{
M##14##C
"NOT available"
}
{
M##14##D
"NOT available"
}
{
M##14##E
"NOT available"
}
{
M##14##F
"NOT available"
}
{
M##14##G
"NOT available"
}
{
M##14##H
"NOT available"
}
{
M##14##K
"NOT available"
}
]
}
,
"15:{
"rchar":"
"rseats":[
{
M##15##A
"NOT available"
}
{
M##15##C
"NOT available"
}
{
M##15##D
"NOT available"
}
{
M##15##E
"NOT available"
}
{
M##15##F
"NOT available"
}
{
M##15##G
"NOT available"
}
{
M##15##H
"NOT available"
}
{
M##15##K
"NOT available"
}
]
}
}
}
,
"Upperdeck" :
{
}
}
请在这里建议我缺少的东西。我被困在这里两天了。
答案 0 :(得分:1)
为了演示此问题,您可以将XSLT简化为此,使用一些硬编码值来保持简单。 (尽管请注意seatNumber
的声明如何简化为<xsl:variable name="seatNumber" select="." />
,而不是第二次重新标记相同的字符串)
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns1="http://www.opentravel.org/OTA/2003/05"
xmlns:str="http://exslt.org/strings" extension-element-prefixes="str">
<xsl:output method="text" />
<xsl:template match="/">
<xsl:variable name="deck" select="'M'" />
<xsl:variable name="rowNumber" select="'11'" />
<xsl:variable name="rowsInDeck" select="//ns1:CabinClass[@cabinLocation=$deck]/../@MaxRow"/>
<xsl:for-each select="str:tokenize($rowsInDeck, '|')">
<xsl:variable name="seatNumber" select="." />
<xsl:value-of select="$deck"/>##<xsl:value-of select="$rowNumber"/>##<xsl:value-of select="$seatNumber"/>
<xsl:if test="boolean(//ns1:CabinClass[@cabinLocation=$deck]/ns1:AirRows/ns1:AirRow[@RowNumber=$rowNumber]/ns1:AirSeats/ns1:AirSeat[@SeatNumber=$seatNumber])">
"available"
</xsl:if>
<xsl:if test="not(boolean(//ns1:CabinClass[@cabinLocation=$deck]/ns1:AirRows/ns1:AirRow[@RowNumber=$rowNumber]/ns1:AirSeats/ns1:AirSeat[@SeatNumber=$seatNumber]))">
"NOT available"
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
问题是,检查可用性的xsl:if
语句是在xsl:for-each
语句的上下文中,该语句标记rowsDeck
变量。这意味着xsl:for-each
中的代码块位于原始文档的不同上下文中。您不是迭代源文档中的节点,而是迭代新创建的原子值。这意味着表达式//ns1:CabinClass
将不起作用,因为您的上下文不再是原始XML。
我有点惊讶你没有得到以下几行的错误:
Leading '/' cannot select the root node of the tree containing the context item: the context item is not a node
无论如何,要解决,您可以通过变量(在xsl:for-each
之前声明)
<xsl:variable name="root" select="/" />
然后,您可以将xsl:if
语句更改为:
<xsl:if test="boolean($root//ns1:CabinClass[@cabinLocation=$deck]/ns1:AirRows/ns1:AirRow[@RowNumber=$rowNumber]/ns1:AirSeats/ns1:AirSeat[@SeatNumber=$seatNumber])">
实际上,在这里使用xsl:choose
可能更好,同样指定表达式两次。此处也不必使用boolean
运算符。当表达式返回一个节点时,如果它存在,if
语句将把它评估为真,如果不存在则将其评估为假。
尝试使用此XSLT作为初学者
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns1="http://www.opentravel.org/OTA/2003/05"
xmlns:str="http://exslt.org/strings" extension-element-prefixes="str">
<xsl:output method="text" />
<xsl:template match="/">
<xsl:variable name="deck" select="'M'" />
<xsl:variable name="rowNumber" select="'11'" />
<xsl:variable name="rowsInDeck" select="//ns1:CabinClass[@cabinLocation=$deck]/../@MaxRow"/>
<xsl:variable name="root" select="/" />
<xsl:for-each select="str:tokenize($rowsInDeck, '|')">
<xsl:variable name="seatNumber" select="." />
<xsl:value-of select="$deck"/>##<xsl:value-of select="$rowNumber"/>##<xsl:value-of select="$seatNumber"/>
<xsl:choose>
<xsl:when test="$root//ns1:CabinClass[@cabinLocation=$deck]/ns1:AirRows/ns1:AirRow[@RowNumber=$rowNumber]/ns1:AirSeats/ns1:AirSeat[@SeatNumber=$seatNumber]">
"available"
</xsl:when>
<xsl:otherwise>
"NOT available"
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>