我具有如下所示的XML结构(示例XML)。我想更改img标签值并将其更改为相对路径。每个XML文档可以包含100多个img标签。我的代码适用于大部分部分,但事实上,我在根节点中拥有的名称空间声明已添加到引用该名称空间的各个节点中,我不希望这种情况发生。
示例XML:
w
在下面的我的SwitchCase代码中,我知道由于$ doc变量声明中的代码“ / *”,分别添加了名称空间,但如果不这样做,我将需要为每个循环添加一个,以破坏其他逻辑。我只想更改img标签属性值,而不更改输出xml中的任何其他内容,请提出解决方法。
XQUERY代码:
v
这是转换后的输出:
<?xml version="1.0" encoding="UTF-8"?>
<test:document transformVersion="0.0.25" xmlns:test="test.data" xmlns:csp="test.csp" xmlns:cfg="test.cfg">
<data>
<table>
<tr>
<td>
<p class="DataboxTitle">Test Image</p>
</td>
<td>
<p>
<img src="https://www.google.com/images/document/1234.jpg" data-stl="height:107px;width:223px;" srcset="https://www.google.com/images/document/1234.jpg 320w" data-image-title="Test Image"/>
</p>
</td>
</tr>
</table>
<table>
<tr>
<td>
<p class="DataboxTitle">Test Image</p>
</td>
<td>
<p>
<img src="https://www.google.com/images/document/1234.jpg" data-stl="height:107px;width:223px;" srcset="https://www.google.com/images/document/1234.jpg 320w" data-image-title="Test Image"/>
</p>
</td>
</tr>
</table>
<table>
<tr>
<td>
<p class="DataboxTitle">Test Image</p>
</td>
<td>
<p>
<img src="https://www.google.com/images/document/1234.jpg" data-stl="height:107px;width:223px;" srcset="https://www.google.com/images/document/1234.jpg 320w" data-image-title="Test Image"/>
</p>
</td>
</tr>
</table>
<p>
<img src="https://www.google.com/images/document/1234.jpg" data-stl="height:107px;width:223px;" srcset="https://www.google.com/images/document/1234.jpg 320w" data-image-title="Test Image"/>
</p>
</data>
<test:volumes>
<test:test>test</test:test>
</test:volumes>
<csp:volumes>tested</csp:volumes>
</test:document>
答案 0 :(得分:1)
将名称空间声明保留在它们出现的元素上并不难,只需确保将它们与属性和元素一起复制过来即可。为此,您可以使用$node/namespace::*
:
declare function local:change($node as node()*) as node()*
{
typeswitch($node)
case element(img) return
element { xs:QName(fn:local-name($node)) }
{
let $image := $node
let $path := xdmp:path($image)
let $data-stl := fn:data($image/@data-stl)
let $data-image-title := fn:data($image/@data-image-title)
let $srcOld := fn:data($image/@src)
let $srcSetsOld := fn:data($image/@srcset)
let $srcNew := local:createTag($docId,$image)
let $srcSetsNew := local:createSrcSetTag($docId,$image)
return (attribute {'src'}{$srcNew}, attribute {'data-stl'}{$data-stl},attribute {'srcset'}{$srcSetsNew}, attribute {'data-image-title'}{$data-image-title} )
}
case element() return
element {fn:node-name($node) } {
$node/namespace::*,
$node/@*,
$node/node() ! local:change(.)
}
default return $node
};
HTH!
答案 1 :(得分:0)
您发布的实现也是测试其他代码的一个很好的例子-通常* XML处理代码不应依赖于名称空间的特定声明样式,而应仅依赖内部XDM模型中的名称空间属性。如果仅由于格式更改而导致代码中断,那将是进行查找和修复此类代码的绝佳单元测试。
**当然,有一些原因使代码明确依赖格式或名称空间声明差异,例如将实现上述单元测试的代码-它需要明确控制结果格式以及检测语义上相同的格式差异,与外部服务进行交互,或者特别是繁琐的工作,从XML中提取子节点并保留所需的(并且仅保留所需的)名称空间,文本序列化优化等,或者-
<expletive deleted>
-生成XHTML。