我需要通过用下划线替换命名空间冒号来修改一些XML标记,这样:
<video:rating>5</video:rating>
<video:view_count>128</video:view_count>
<video:publication_date>2017-02-25T00:25:44+00:00</video:publication_date>
将成为这个:
<video_rating>5</video_rating>
<video_view_count>128</video_view_count>
<video_publication_date>2017-02-25T00:25:44+00:00</video_publication_date>
请注意,日期中的冒号没有更改。我正在尝试创建一个可捕获“ <”和“>”之间任何冒号的正则表达式,然后将其替换为“ _”,但是我是一个正则表达式菜鸟,因此证明它是不可能的:^)
答案 0 :(得分:1)
如果要避免意外的结果,最好在处理XML时始终使用为XML设计的工具。
假设您有一个这样的站点地图文件:
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:video="http://www.google.com/schemas/sitemap-video/1.1">
<url>
<loc>http://example.com/video-page.html</loc>
<video:video>
<video:thumbnail_loc>http://example.com/thumb1.jpg</video:thumbnail_loc>
<video:title>Clown in the garden</video:title>
<video:description>Crazy clown is riding a rabbit.</video:description>
<video:content_loc>http://www.example.com/video1.mp4</video:content_loc>
</video:video>
</url>
</urlset>
要将具有名称空间“ video”的元素更改为默认名称空间中具有“ video_”开头的本地名称的元素,可以使用XSLT(可扩展样式表语言转换)定义模板,在其中可以编辑xml的元素文献。这些样式表使用xpath语言精确定位所需的元素。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:video="http://www.google.com/schemas/sitemap-video/1.1">
<xsl:output indent="yes" encoding="UTF-8"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="video:*">
<xsl:element name="{concat('video_', local-name(.))}">
<xsl:copy-of select="@*"/>
<xsl:apply-templates select="node()|@*"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
请注意,您需要两个模板:第一个(通常称为 identity 模板)复制所有文档,第二个仅处理“视频”命名空间中的标记。
那么您在PHP代码中要做的就是将XSLT应用于XML文档:
$xmldoc = new DOMDocument;
$xmldoc->load($sitemapFile);
$xsldoc = new DOMDocument;
$xsldoc->load($stylesheetFile);
$xsl = new XSLTProcessor();
$xsl->importStyleSheet($xsldoc);
echo $xsl->transformToXML($xmldoc);
答案 1 :(得分:-3)
这是一个PHP示例片段。
正则表达式仅使用标记内的冒号,以下划线代替。
<?php
$str = '<video:rating>5</video:rating>
<video:view_count>128</video:view_count>
<video:publication_date>2017-02-25T00:25:44+00:00</video:publication_date>';
$result = preg_replace('@</?\w+\K:(?=\w+>)@m', '_', $str);
echo '<br/><br/><strong>BEFORE</strong><br/>';
echo htmlentities($str);
echo '<br/><br/><strong>AFTER</strong><br/><br/>';
echo htmlentities($result);
您可以测试正则表达式here on regex101