哪种语言最容易、最快速地处理XML内容?

23

我们有会 Ruby、Python、.Net 或 Java 的开发人员。我们正在开发一个主要处理 XML 文档的应用程序。大部分工作是将预定义的 XML 文件转换为数据库表,通过数据库提供 XML 文档之间的映射,并从数据库创建报告等。哪种语言最容易且最快速地完成这项工作?(这是一个 web 应用程序)


你使用的是哪种数据库?它很可能支持本地XML处理。如果是这样,这可能是一个可行的替代方案。 - Rune Grimstad
9个回答

20

这里使用动态语言规则。为什么呢?因为映射很容易编码和更改,无需重新编译和重建。

实际上,只要稍微聪明一点,您就可以将“XML XPATH到标记 -> DB表字段”的映射作为Python代码的不连续块导入到主应用程序中。

Python代码块您的配置文件。它不是描述配置的.ini文件或.properties文件,而是配置本身。

我们使用Python、xml.etree和SQLAlchemy(将SQL从程序中分离出来)进行此操作,因为我们可以轻松快速地启动,并具有极大的灵活性。


source.py

"""A particular XML parser.  Formats change, so sometimes this changes, too."""

import xml.etree.ElementTree as xml

class SSXML_Source( object ):
    ns0= "urn:schemas-microsoft-com:office:spreadsheet"
    ns1= "urn:schemas-microsoft-com:office:excel"
    def __init__( self, aFileName, *sheets ):
        """Initialize a XML source.
        XXX - Create better sheet filtering here, in the constructor.
        @param aFileName: the file name.
        """
        super( SSXML_Source, self ).__init__( aFileName )
        self.log= logging.getLogger( "source.PCIX_XLS" )
        self.dom= etree.parse( aFileName ).getroot()
    def sheets( self ):
        for wb in self.dom.getiterator("{%s}Workbook" % ( self.ns0, ) ):
            for ws in wb.getiterator( "{%s}Worksheet" % ( self.ns0, ) ):
                yield ws
    def rows( self ):
        for s in self.sheets():
            print s.attrib["{%s}Name" % ( self.ns0, ) ]
            for t in s.getiterator( "{%s}Table" % ( self.ns0, ) ):
                for r in t.getiterator( "{%s}Row" % ( self.ns0, ) ):
                    # The XML may not be really useful.
                    # In some cases, you may have to convert to something useful
                    yield r

model.py

"""This is your target object.  
It's part of the problem domain; it rarely changes.
"""
class MyTargetObject( object ):
    def __init__( self ):
        self.someAttr= ""
        self.anotherAttr= ""
        self.this= 0
        self.that= 3.14159
    def aMethod( self ):
        """etc."""
        pass

builder_today.py 是众多映射配置之一。

"""One of many builders.  This changes all the time to fit
specific needs and situations.  The goal is to keep this
short and to-the-point so that it has the mapping and nothing
but the mapping.
"""

import model

class MyTargetBuilder( object ):
    def makeFromXML( self, element ):
        result= model.MyTargetObject()
        result.someAttr= element.findtext( "Some" )
        result.anotherAttr= element.findtext( "Another" )
        result.this= int( element.findtext( "This" ) )
        result.that= float( element.findtext( "that" ) )
        return result

loader.py

"""An application that maps from XML to the domain object
using a configurable "builder".
"""
import model
import source
import builder_1
import builder_2
import builder_today

# Configure this:  pick a builder is appropriate for the data:
b= builder_today.MyTargetBuilder()

s= source.SSXML_Source( sys.argv[1] )
for r in s.rows():
    data= b.makeFromXML( r )
    # ... persist data with a DB save or file write

要进行更改,您可以更正构建器或创建新的构建器。您可以调整加载程序源以确定将使用哪个构建器。您可以很容易地将构建器的选择作为命令行参数。动态语言中的动态导入似乎对我来说过于繁琐,但它们非常方便。


请稍微详细地解释一下。 - Varun Mahajan
我还想为lxml喊一声,它为libxml2提供了Pythonic绑定。除了构建etree之外,它还提供了更完整的xpath支持,而不仅仅是elementtree。 - Aaron Maenpaa
我尝试过在C#,PHP,Java和Python中进行XML处理,最后Python胜出。它更容易,更清晰,并且已经有自动执行大部分映射的工具。 - Bite code
你开始说:“这需要一种动态语言。为什么?因为映射易于编码和更改,无需重新编译和重建。”如果你在通常的PL意义上使用静态语言,那么你会混淆动态和解释。 - ja.
“将动态与解释混淆”?你需要为我提供一些关于动态和解释之间的区别的帮助。我不知道它们有什么区别。 - S.Lott

8
在.NET中,C# 3.0和VB9使用LINQ to XML提供了出色的支持,用于处理XML:

LINQ to XML概述


8

XSLT

我建议使用XSLT模板将XML转换为所需的INSERT语句(或其他内容)。
您应该能够从您提到的任何语言中调用XSLT。

这将比通过其他方式完成所需代码量少得多。


XSLT不起作用,因为我们还必须将文件之间的映射保存在数据库中。 - Varun Mahajan
您可以使用现有的(或自己的)扩展函数或扩展元素来编写/更新数据库中的表行。例如,Saxon具有以下7种类型的扩展元素:sql:connect、sql:query、sql:insert、sql:column、sql:update、sql:delete和sql:close。 - Dimitre Novatchev
我不同意。XSLT 可以将 XML 转换为 XML,但这并不能满足此处的需求(至少不能将其转换为 SQL 语句)。而且,我发现 XSLT 难以处理:工具少,难以测试、调试、阅读,性能通常较低。 - rds
XSLT 可用于生成任何文本输出。输出不一定是 XML。我也觉得它很难使用:我不是每天都使用它,而且很难理解它的工作方式。尽管如此,工具正在改进,当我使用它时,与使用过程式语言相比,我可以节省很多时间。 - AJ.

4

为了快速完成,我发现 Groovy非常有用。


1
值得一提的是,使用Groovy意味着可以访问Java的XML解析库,特别是它们的XPath支持,而不需要太多Java实现中常见的样板代码。 - Aaron Maenpaa
我曾经发现Groovy非常缓慢且资源消耗巨大。 - Mark K Cowan

4
我会提供一个建议,使用流行的Ruby XML解析器Hpricot(虽然有许多类似的选项)。
示例:
给定以下XML:
<Export>
  <Product>
    <SKU>403276</SKU>
    <ItemName>Trivet</ItemName>
    <CollectionNo>0</CollectionNo>
    <Pages>0</Pages>
  </Product>
</Export>

你可以简单地解析:

FIELDS = %w[SKU ItemName CollectionNo Pages]

doc = Hpricot.parse(File.read("my.xml")) 
(doc/:product).each do |xml_product|
  product = Product.new
  for field in FIELDS
    product[field] = (xml_product/field.intern).first.innerHTML
  end
  product.save
end

看起来你的应用程序非常适合使用Rails应用程序,你可以快速原型化所需内容,直接与所选数据库进行交互,并以任何需要的方式输出数据。

这是另一个很棒的资源页面使用Hpricot解析XML,可能会有帮助,还有文档


2

使用LiNQ to XML,可以使用C#或VB.Net轻松实现。LiNQ to XML非常强大且易于实现。


2
一种有趣的解决方案可能是Ruby。只需使用XML->对象映射器,然后使用对象关系映射器(ORM)将其放入数据库中。我曾经做过一次有关Ruby XML映射的简短演讲,您可以查看幻灯片,看看哪个最好: http://www.marc-seeger.de/2008/11/25/ruby-xml-mapping/
至于ORM:Active Record或Datamapper应该是正确的选择。

2

ECMAScript可以使用E4X("ECMAScript for XML")很好地处理XML。这可以在Adobe的最新版本的ActionScript 3中看到。我相信JavaScript 2(我认为将与Firefox 4一起发布)也将支持E4X。

不确定独立的JavaScript解释器(即Rhino等)是否支持此功能,这可能是您最关心的问题...但如果它对您有用,请随时查找它们对其的支持情况(并向我们报告:-))。

请参见http://en.wikipedia.org/wiki/E4X#Example以获取简单示例。


1
是的,JavaScript可以是一个非常好的答案。当与jQuery结合使用时,效果更佳。 - rds

-1
如果您精通Java,可以尝试使用VTD XML解析器来解析大量的XML数据。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接