我想提取元素结束标记之前的文本节点a
。例如,对于此示例 XML:
<root>
<a/>
<a>1</a>
<a>2<b/>3</a>
<a>4<b/></a>
<a><b/>5<c/></a>
</root>
预期结果将是序列( 1, 3 )
该表达式//a/text()[last()]
是不够的,因为它返回( 1, 3, 4, 5 )
,问题是我不知道如何添加约束:“就在”的结束标记之前a
。
我想提取元素结束标记之前的文本节点a
。例如,对于此示例 XML:
<root>
<a/>
<a>1</a>
<a>2<b/>3</a>
<a>4<b/></a>
<a><b/>5<c/></a>
</root>
预期结果将是序列( 1, 3 )
该表达式//a/text()[last()]
是不够的,因为它返回( 1, 3, 4, 5 )
,问题是我不知道如何添加约束:“就在”的结束标记之前a
。
我有一个 XML 文件:
<books>
<title>Moby-Dick</title>
<author>Herman Melville</author>
<title>Sunrise Nights</title>
<author>Jeff Zentner</author>
<author>Brittany Cavallaro</author>
<price>14.52€</price>
<title>My Salty Mary</title>
<author>Cynthia Hand</author>
<author>Brodi Ashton</author>
<author>Jodi Meadows</author>
</books>
我想将其转换为:
<books>
<book>
<title>Moby-Dick</title>
<author>Herman Melville</author>
</book>
<book>
<title>Sunrise Nights</title>
<author>Jeff Zentner</author>
<author>Brittany Cavallaro</author>
<price>14.52€</price>
</book>
<book>
<title>My Salty Mary</title>
<author>Cynthia Hand</author>
<author>Brodi Ashton</author>
<author>Jodi Meadows</author>
</book>
</books>
逻辑是,book
每次我们遇到一个时就创建一个新的title
,并将每个后续的“非标题”节点放入该书中。
以下是我迄今为止尝试过的:
let $books := (
doc("books.xml")/books/* =>
fold-left((array{}, 0), function($acc, $node) {
let
$arr := $acc[1],
$idx := $acc[2]
return
if (name($node) = "title")
then ($arr => array:append($node), $idx+1)
else ($arr => array:put($idx, ($arr($idx), $node)), $idx)
})
)[1]
return
<books>{
for $book in $books
return <book>{$book}</book>
}</books>
但我明白
<books>
<book>
<title>Moby-Dick</title>
<author>Herman Melville</author>
<title>Sunrise Nights</title>
<author>Jeff Zentner</author>
<author>Brittany Cavallaro</author>
<price>14.52€</price>
<title>My Salty Mary</title>
<author>Cynthia Hand</author>
<author>Brodi Ashton</author>
<author>Jodi Meadows</author>
</book>
</books>
旁白: group by
这似乎对解决当前问题没有用,所以我尝试将书籍分组到一个数组中,但我不知道这是否是正确的方法;欢迎任何建议。
我想要采取一系列的映射并找到不同的值,显而易见的事情是。
<xsl:variable name="sequence" select="
( map { 'foo' : 1, 'bar' : () },
map { 'foo' : 1, 'bar' : '3' },
map { 'foo' : 1, 'bar' : '3' } )" as="map(xs:string,item()*)*"/>
<xsl:variable name="distinct" select="distinct-values($sequence)"/>
但这引发了警告
Error in xsl:variable/@select on line 29 column 76 of PurchasableSeasonOG.content.xsl: FOTY0013 An atomic value is required for the first argument of fn:distinct-values(), but the supplied type is a map type, which cannot be atomized
即地图不是原子值,足够公平。
我期待答案是
( map { 'foo' : 1, 'bar' : () },
map { 'foo' : 1, 'bar' : '3' } )
但你该怎么做呢?
附言
我可以看到如何使用硬编码的 for-each-group 来执行此操作,甚至构建一个递归函数通过 for-each-group 来执行此操作,但我希望 XPath 工具箱中有可以执行此操作的函数,而且我正在努力按可以是空序列的键进行分组。
我在这里看到过很多次这样的问题,但这次非常不同。其他使用 IMPORTXML 的帮助请求中,楼主询问的是提取标准 HTML 标签,如 a/href/img/src/ul/li 等。我想要提取的内容嵌入在 style 标签中,但提取结果并不如预期。
在此页面https://www.northtexasgivingday.org/organization/Salvationarmynorthtexas(以及一系列类似的页面)上,我尝试提取各种非营利组织徽标的 URL。
我在 Chrome 开发工具中突出显示了徽标并复制了 Xpath 或完整的 Xpath - 它没有使用 IMPORTXML 返回预期的徽标 url。
xapth 是 //*[@id="org-logo"]/span 并且完整的 Xpath 是 /html/body/app-root/mat-sidenav-container/mat-sidenav-content/div[2]/app-organization/div/app-org-page/div/div/div[1]/app-banner/div/div[3]/span
The image is stored in this element:
<span _ngcontent-ng-c332306571="" role="img" applazyload="" class="image set-background ng-star-inserted" aria-label="The Salvation Army North Texaslogo" style="opacity: 0; animation: 0.7s ease-out 0s 1 normal forwards running lazy-load-anim1; background-repeat: no-repeat; background-size: cover; width: 100%; height: 100%; background-position: center center; background-image: url("https://imagecdn.mightycause.com/36be848e-03bb-47c3-8616-6d51b811e38d/-/format/auto/-/progressive/yes/-/stretch/off/-/preview/");"></span>
我可以在样式部分下的元素中看到图像网址
background-image:
我已经在以下公式中尝试了两个 Xapth 选项:
IMPORTXML(“https://www.northtexasgivingday.org/organization/Salvationarmynorthtexas”,“//*[@id='org-logo']/span”)
或者
IMPORTXML(“https://www.northtexasgivingday.org/organization/Salvationarmynorthtexas”,“/html/body/app-root/mat-sidenav-container/mat-sidenav-content/div[2]/app-organization/div/app-org-page/div/div/div[1]/app-banner/div/div[3]/span”)
这些都不起作用。你们能帮我解决这个问题吗?
我正在尝试重新制作列表列表,从 XML 转换为专有的基于 XML 的文件格式。
本质上输入是这样的
<ul>
<li>Item 1</li>
<li><ul><li>Sub item 1</li><li>Sub item 2</li></ul></li>
<li>Item 2</li>
<li><ul><li>Sub item 3</li><li>Sub item 4</li></ul></li>
</ul>
显然看起来像这样:
但我需要子项列表li
与其各自的标题位于同一个标签内。因此,如下所示:
当我测试上面的原始输入时,我似乎无法想出一个 XPATH,它会选择我的第一个子项ul
而不选择第二个子项ul
。
当通过转换运行时,这基本上会创建
<ul>
<li>Item 1
<ul><li>Sub item 1</li><li>Sub item 2</li></ul>
<ul><li>Sub item 3</li><li>Sub item 4</li></ul>
</li>
<li>Item 2
<ul><li>Sub item 3</li><li>Sub item 4</li></ul>
</li>
</ul>
让我走到这一步的 XPath 是
following-sibling::li[not(normalize-space(text()))]/*[1][self::ul or self::ol]
normalize-space 是隔离li
没有文本但里面只有ul
或的ol
元素。我尝试了上述的多种变体,设置索引 [1] 只会返回所有元素,而 [2] 则不返回任何元素。
我有点困惑,感谢任何意见或建议!
我有一个事件列表,其内容如下:
<div class="all-ebents">
<div class="sport-base-event">
<span class="event-block-current-time__time--VEuoj">63:07</span>
<span class="event-block-score">0:0</span></div>
</div>
<div class="sport-base-event">
<span class="event-block-current-time__time--VEuoj">64:07</span>
<span class="event-block-score">0:1</span></div>
</div>
<div class="sport-base-event">
<span class="event-block-current-time__time--VEuoj">63:07</span>
<span class="event-block-score">0:1</span></div>
</div>
</div>
到目前为止,我已经能够使用以下代码获取事件时间值和计数
//*[contains(@class, "event-block-current-time--")]::text() # get the time block
//*[contains(@class, "event-block-current-time--")]/following-sibling::div::text() # score block
如果事件时间包含值 63 并且相邻元素中的分数为 0:0,那么绕过这些查询并获取父元素的正确方法是什么?
我浏览了前三页搜索页中的所有答案,但无法得到解决方案;第二页之后的问题甚至都不相关。
在此 RSS 源中:
<?xml version="1.0" encoding="utf-8"?>
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
xmlns="http://purl.org/rss/1.0/">
<channel rdf:about="https://www.myfeed.tld/">
<title>My Feed</title>
<link>https://www.myfeed.tld/</link>
</channel>
<item rdf:about="https://www.myfeed.tld/mypost">
<title><![CDATA[Posting to SO SO Good]]></title>
<link>https://www.myfeed.tld/mypost</link>
<dc:date>2024-06-19T07:48:00-05:00</dc:date>
</item>
</rdf:RDF>
我需要获取以下文本内容:
<rdf:RDF><channel><title>
<rdf:RDF><item><title>
<rdf:RDF><item><dc:date>
根据这个答案,我认为我应该能够使用:
xmllint --xpath "//*[local-name()='rdf:RDF']/channel/title/text()" feed.rss
xmllint --xpath "//*[local-name()='rdf:RDF']/item/title/text()" feed.rss
xmllint --xpath "//*[local-name()='rdf:RDF']/item/*[local-name()='dc:date']/text()" feed.rss
我尝试了每一个变体,但我只得到:XPath set is empty
我在节点中有一些文本,例如:
<xml><Hello world "&" foo bar></xml>
我想string(/xml)
对其进行处理和 JSON 转义,以便结果类似于:
"<Hello world \"&\" foo bar>"
我怎样才能用 XPath 3.1 做到这一点?
是否有一个函数可以测试(或返回) 的类型.
?例如:
( root(), (), "a", 1, map{}, array{} ) ! unknown:type-of(.)
node
sequence
string
number
map
array