我有一个XML代码段,所以:
<STATES>
<STATE>
<NAME>Alabama</NAME>
<ABBREVIATION>AL</ABBREVIATION>
<CAPITAL>Montgomery</CAPITAL>
<POPULATION>4661900</POPULATION>
<AREA>52419</AREA>
<DATEOFSTATEHOOD>14 December 1819</DATEOFSTATEHOOD>
</STATE>
<STATE>
<NAME>Alaska</NAME>
<ABBREVIATION>AK</ABBREVIATION>
<CAPITAL>Juneau</CAPITAL>
<POPULATION>698473</POPULATION>
<AREA>663268</AREA>
<DATEOFSTATEHOOD>1 January 1959</DATEOFSTATEHOOD>
</STATE>
<STATE>
<NAME>Delaware</NAME>
<ABBREVIATION>DE</ABBREVIATION>
<CAPITAL>Dover</CAPITAL>
<POPULATION>885122</POPULATION>
<AREA>2490</AREA>
<DATEOFSTATEHOOD>7 December 1787</DATEOFSTATEHOOD>
</STATE>
</STATES>
<etc, etc.>
我想检索(例如)最古老州的首府(即“Dover”)。 我设法做到这一点:
//STATES/STATE[DATEOFSTATEHOOD='7 December 1787']/CAPITAL/text()
但无法弄清楚怎么说'DATEOFSTATEHOOD = {最早的DATEOFSTATEHOOD}'。
有人能指出我正确的方向吗?
解决方案:马特的解决方案或多或少都是现货。我不得不重新格式化日期(我使用了YYYYMMDDD),因为正如所指出的,Xpath 1.0不支持我使用的日期格式。此外,Microsoft的XML库(4.0和6.0)使用Matt的表达式返回整个节点列表。反转测试修复了该问题,使其仅返回最早的节点。
所以:
//STATES/STATE[(DATEOFSTATEHOOD < //STATES/STATE/DATEOFSTATEHOOD)]/CAPITAL/text()
答案 0 :(得分:3)
XPATH 1.0不支持您提供的格式的日期。如果您能够使用这些日期的数字表示,例如17871207,那么您可以轻松地这样做:
//STATES/STATE[not(DATEOFSTATEHOOD > //STATES/STATE/DATEOFSTATEHOOD)]/CAPITAL/text()
如果这不可行,则可能值得尝试将DATEOFSTATEHOOD
节点格式化为xs:date
并执行相同的操作:
//STATES/STATE[not(xs:date(DATEOFSTATEHOOD) > xs:date(//STATES/STATE/DATEOFSTATEHOOD))]/CAPITAL/text()
语法可能不完全正确,但希望它能让你开始。
答案 1 :(得分:1)
你能把它们重新格式化为xs:dates?
let $dates := (xs:date('2000-10-23'), xs:date('1999-12-26'))
let $min := fn:min($dates)
let $max := fn:max($dates)
return $min
在MarkLogic Server中完成,但我认为这都是标准的东西。
答案 2 :(得分:1)
您可以使用XQuery重新格式化日期,并使用min()找到最早的日期:
declare variable $monthnames := ("January","February","March","April","May","June","July","August","September","October","November","December");
declare function local:pad-zero($s as xs:string) as xs:string {
if (string-length($s) = 1) then concat("0",$s) else $s
};
declare function local:df ($d as xs:string) as xs:date {
let $dp := tokenize($d," ")
let $year := $dp[3]
let $month := local:pad-zero(string(index-of($monthnames,$dp[2])))
let $day := local:pad-zero($dp[1])
return
concat($year,"-",$month,"-",$day)
};
let $states :=
<STATES>
<STATE>
<NAME>Alabama</NAME>
<ABBREVIATION>AL</ABBREVIATION>
<CAPITAL>Montgomery</CAPITAL>
<POPULATION>4661900</POPULATION>
<AREA>52419</AREA>
<DATEOFSTATEHOOD>14 December 1819</DATEOFSTATEHOOD>
</STATE>
<STATE>
<NAME>Alaska</NAME>
<ABBREVIATION>AK</ABBREVIATION>
<CAPITAL>Juneau</CAPITAL>
<POPULATION>698473</POPULATION>
<AREA>663268</AREA>
<DATEOFSTATEHOOD>1 January 1959</DATEOFSTATEHOOD>
</STATE>
<STATE>
<NAME>Delaware</NAME>
<ABBREVIATION>DE</ABBREVIATION>
<CAPITAL>Dover</CAPITAL>
<POPULATION>885122</POPULATION>
<AREA>2490</AREA>
<DATEOFSTATEHOOD>7 December 1787</DATEOFSTATEHOOD>
</STATE>
</STATES>
return
$states//STATE
[local:df(DATEOFSTATEHOOD) =
min($states//STATE/local:df(DATEOFSTATEHOOD))
]
您可以在eXist sandbox
中执行此操作