正则表达式/解析XML文件

时间:2011-06-12 02:58:57

标签: xml regex xml-parsing

我有一个XML文件,其中包含自定义标记包含的大量数据。这对我所拥有的一个项目都很有用,但对于另一个项目我不需要那么多信息。因此,我想修剪XML文件,并删除某些标记的所有实例以及标记之间的任何内容。

<GOBJ>
    <cost>4</cost>
    <duration>n/a</duration>
    <item>Stone Block</item>
    <type>Construction - Material</type>
    <misc>Use these blocks to build things. These blocks don't degrade.</misc>
</GOBJ>

我只想保留[item]blah[item][type]blah[type],其余内容应删除/删除。

稍后,我需要检查[type]的文本,如果它与某些单词匹配,则替换其内容。例如,如果单词metal位于[type]标记内的任何位置,则将该标记的内容替换为单词metal。

我知道这是一个很大的要求;我感谢任何帮助。

5 个答案:

答案 0 :(得分:2)

另一种方法是使用简单的XML→XML(带有XPath 1.0的XSLT 1.0)转换,如下所示。它很容易适应您的要求并重复用于其他文档。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

    <xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>

    <xsl:template match="root">
        <root>
            <xsl:apply-templates select="GOBJ"/>
        </root>
    </xsl:template>

    <xsl:template match="GOBJ">
        <GOBJ>
            <xsl:copy-of select="item"/>
            <type>
                <xsl:choose>
                    <xsl:when test="contains(type, 'metal')">
                        <xsl:text>metal</xsl:text>
                    </xsl:when>
                    <!-- other xsl:when conditions here -->
                    <xsl:otherwise>
                        <xsl:value-of select="type"/>
                    </xsl:otherwise>
                </xsl:choose>
            </type>
        </GOBJ>
    </xsl:template>
</xsl:stylesheet>

我知道它不是基于正则表达式的解决方案,但恕我直言,最好使用原生的面向XML的工具包。

答案 1 :(得分:0)

假设文件的布局与您的示例完全相同,则乘以所需数量的记录,并希望尽可能保留原始布局,替换

(<GOBJ>[^<]+?).+?(<item>.+?<\/type>\n).+?(<\/GOBJ>)

$1$2$3

全局并且正则表达式设置为以“单行”模式运行,将执行您需要的iff,元素<GOBJ>为大写,其他元素为小写,每个记录每个元素只有一个实例,元素<item>始终显示在每个记录中元素<type>之前。

在JavaScript中,这将是:

var result = src.replace(
    /(<GOBJ>[^<]+?).+?(<item>.+?<\/type>\n).+?(<\/GOBJ>)/g, 
    '$1$2$3'
);

请注意,严格条件可以缓解与使用正则表达式解析XML相关的任何问题。如果无法满足条件,那么使用特定于XML的工具(如XSLT)可以提供更好的服务。

答案 2 :(得分:0)

这是一个grep解决方案:grep -E '(<item>|<type>)' myfile.xml

答案 3 :(得分:0)

我开发了另一种解决问题的方法;我构建了一个jquery脚本,它分割了xml代码(我用手前的不同符号替换了所有左/右箭头),如果我没有包含另一个特定符号,则输出数组条目。

var name = $('div').text().trim().split(/\[name\](.*?)\[\/name\]/g);
var type = $('div').text().trim().split(/\[type\](.*?)\[\/type\]/g);
for (i = 0; name.length > i; i++) {
        if ((type[i].match(/\[/g))) {
            type[i] = "";
        }
        if (!(name[i].match(/\[/g))) {
            if (type[i].match(/construction/g)) {type[i] = "T_C";}
            if (type[i].match(/material/g)) {type[i] = "T_M";}
            if (type[i].match(/metalwork/g)) {type[i] = "T_W";}
            if (type[i].match(/water/g)) {type[i] = "T_W";}
            if (type[i].match(/oil/g)) {type[i] = "T_O";}
            if (type[i].match(/precious/g)) {type[i] = "T_P";}
            if (type[i].match(/magic/g)) {type[i] = "T_M";}
            $('.Collect').append('<p>a href="../Img/XXX/' + name[i] + '.jpg" class="' + type[i] + '">' + name[i] + '/a></p>');
        } else {
            name[i] = "";
        }

    }

输出的格式是这样的,这样我就可以将页面复制粘贴到txt / html文件中,并按照我想要的方式使用它。我将不得不想办法用适当的目录名替换XXX ...

我只需要做一次或两次,所以纯粹的自动化并不是必须的。

答案 4 :(得分:0)

如果要解析XML日志文件,以便可以使用正则表达式{java},if (changing_array == final_array) { Console.WriteLine("It took {0} passes to sort \n{1} \ninto \n{2} ", pass_count, starting_array, final_array); sorted = true; } else { Console.WriteLine("End of pass {0}. \n{1} \nis now \n{2} ", pass_count, starting_array, changing_array); break;//this is what will prevent infinite loop } 。那么您将获得<[^<]+<。输出类似于 name> DEV