【问题标题】:Match all <g> and <image> tag except one containing a specific string匹配所有 <g> 和 <image> 标记,但包含特定字符串的标记除外
【发布时间】:2018-09-23 21:54:46
【问题描述】:

我有一个 SVG 文件,我想删除其中的所有标签和图像标签,除了一个标签,其 href 链接包含“艺术品”。我使用 php,为了方便,这里是 SVG 文件的内容。请注意,为了使正则表达式更简单,SVG 文件将删除换行符。

到目前为止,我的正则表达式是:

(<g transform="(?:.*)?"><\/image><\/g>)  

匹配所有标签和里面的图片标签

<?xml version="1.0" encoding="UTF-8" standalone="no" ?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="100%" height="100%" viewBox="0 0 1879 2053" xml:space="preserve"><desc>Created with Fabric.js 1.6.2</desc>
<defs></defs>
<g transform="translate(939.5 1026.5)">
<image xlink:href="/home/printplusprod/public_html/media/pdp/images/filename1462961406.jpg" x="-939.5" y="-1026.5" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;" width="1879" height="2053" preserveAspectRatio="none"></image>
</g>
<g transform="translate(939.51 1026.5) scale(2.59 2.59)">
<image xlink:href="/home/printplusprod/public_html/media/pdp/images/overlay1462961406.png" x="-362.22" y="-395.76" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;" width="724.44" height="791.52" preserveAspectRatio="none"></image>
</g>
<rect x="-362" y="-395.5" rx="0" ry="0" width="724" height="791" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(0,0,0); fill-opacity: 0; fill-rule: nonzero; opacity: 1;" transform="translate(940.23 1027.12) scale(2.59 2.59)"/>
<g transform="translate(938.93 1025.83) scale(2.59 2.59)">
<image xlink:href="/home/printplusprod/public_html/media/pdp/images/filename1462961406.jpg" x="-362" y="-395.5" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;" width="724" height="791" preserveAspectRatio="xMinYMin slice"></image>
</g>
<g transform="translate(784.5 1177.09) scale(1.5 1.5)">
<image xlink:href="/home/printplusprod/public_html/media/pdp/images/artworks/filename1453713655.jpg" x="-240" y="-179.875" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;" width="480" height="359.75" preserveAspectRatio="none"></image>
</g>
<g transform="translate(938.93 1025.83)">
<image xlink:href="/home/printplusprod/public_html/media/pdp/images/overlay1462961406.png" x="-938.9347705562002" y="-1025.8251429695501" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;" width="1877.8695411124004" height="2051.6502859391003" preserveAspectRatio="none"></image>
</g>
</svg>

【问题讨论】:

  • 使用 XPath,而不是正则表达式。
  • XPath //*[name()="g" and ./*[name()="image" and not(contains(@href, "artworks"))]] 应该可以解决问题
  • 使用 XPath 的演示:3v4l.org/WrnWM

标签: php regex xml


【解决方案1】:

虽然 XPath 允许您在 XML 文档中找到比正则表达式更好的元素,但使用 DOMDocument 并只需遍历所有 &lt;image&gt; 节点即可轻松解决此问题。

下面的代码使用getElementsByTagName() 查找所有&lt;image&gt; 节点并检查href 属性并检查它是否包含“艺术品”。如果不是,则删除该节点(使用parentNode 跟踪从图像标签到&lt;g&gt; 节点)。

$xml = new DOMDocument();
$xml->loadXML($data);
$images = $xml->getElementsByTagName("image");
for ( $i = $images->length-1; $i>= 0; $i-- )   {
    $image = $images->item($i);
    if ( strpos($image->attributes->getNamedItem("href")->nodeValue, "artworks") === false )   {
        $g = $image->parentNode;
        $g->parentNode->removeChild($g);
    }
}

这假定 $data 是 SVG 的实际内容,如果需要直接从文件加载,则需要更改它。

看起来很奇怪的一件事是它实际上是向后遍历&lt;image&gt; 节点,原因是当您删除节点时,顺序会改变,因此删除较早的节点会移动后续节点。反向执行此操作可解决此问题。

上面的例子,结果是……

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="100%" height="100%" viewBox="0 0 1879 2053" xml:space="preserve"><desc>Created with Fabric.js 1.6.2</desc>
<defs/>


<rect x="-362" y="-395.5" rx="0" ry="0" width="724" height="791" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(0,0,0); fill-opacity: 0; fill-rule: nonzero; opacity: 1;" transform="translate(940.23 1027.12) scale(2.59 2.59)"/>

<g transform="translate(784.5 1177.09) scale(1.5 1.5)">
<image xlink:href="/home/printplusprod/public_html/media/pdp/images/artworks/filename1453713655.jpg" x="-240" y="-179.875" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;" width="480" height="359.75" preserveAspectRatio="none"/>
</g>

</svg>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-21
    • 1970-01-01
    • 1970-01-01
    • 2015-01-14
    • 1970-01-01
    • 2012-09-05
    • 1970-01-01
    相关资源
    最近更新 更多