我当然可以使用正则表达式来解析XML中的数据。
<?xml version="1.0"?>
<definitions>
<message name="notificationInput">
<part name="body" element="xsd:notificationRequest" />
</message>
<message name="notificationOutput">
<part name="body" element="xsd:notificationResponse" />
</message>
</definitions>
类似
的模式/<message.*name="(.*)".*part.*name=".*".*element="xsd:(.*)".*<'/message>/sUg
可能会给我想要的数据,这里显示为PHP数组:
array(
array("notificationInput", "body", "notificationRequest"),
array("notificationOutput", "body", "notificationResponse")
)
这当然是非常麻烦和容易出错的。
我知道如何使用XPath来查询完整的节点,但我不认为我可以告诉它"我想要属性name
和element
从节点/definitions/message/part
和每个结果,我也想要属性name
从它的父"。
现在我想知道是否有某种语言或技术(最好是PHP实现)可以用来指定我想提取的数据。
换句话说,我正在寻找一种或多或少可以配置而不是编程的解决方案,因为我有相当多的类似定义来提取。
您可以使用XPath
//message/@name|//message[@name]/part/@name|//message/part/@element
生成所有所需属性的一维序列(抱歉,这是在Python中):
In [366]: doc.xpath('//message/@name|//message[@name]/part/@name|//message/part/@element')
Out[366]:
['notificationInput',
'body',
'xsd:notificationRequest',
'notificationOutput',
'body',
'xsd:notificationResponse']
,然后使用array_chunk
将结果重新排列为3组。(注意,您仍然需要使用一点正则表达式或字符串操作来从notificationResponse
中删除xsd:
,但这仍然比使用正则表达式解析XML更容易和更健壮。
XPath将收集所有属性,即使每个<message>
有多个<part>
。
这个简短的XPath 1.0表达式选择所有需要的属性节点:
/*//*/@*
然后对于每个选定的节点,你可以使用PHP(我不知道)获得它的字符串值。
如果可以使用XPath 2.0,那么所有需要的值都是通过计算类似的表达式产生的:
/*//*/@*/data(.)
下面是一个简单的XSLT 2.0转换,它只计算上述表达式并输出结果:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:sequence select="/*//*/@*/data(.)"/>
</xsl:template>
</xsl:stylesheet>
当对提供的XML文档应用此转换时:
<definitions>
<message name="notificationInput">
<part name="body" element="xsd:notificationRequest" />
</message>
<message name="notificationOutput">
<part name="body" element="xsd:notificationResponse" />
</message>
</definitions>
生成所需的结果:
notificationInput body xsd:notificationRequest notificationOutput body xsd:notificationResponse
我知道不建议用正则表达式解析html,除非你知道所涉及的字符集是什么,但我发布这个答案,因为它可能对你有用。
对于您提供的示例文本,您可以使用如下的简单正则表达式:([a-z]+)"
演示工作Php
代码:
$re = "/([a-z]+)'"/i";
$str = "<?xml version='"1.0'"?>'n<definitions>'n <message name='"notificationInput'">'n <part name='"body'" element='"xsd:notificationRequest'" />'n </message>'n <message name='"notificationOutput'">'n <part name='"body'" element='"xsd:notificationResponse'" />'n </message>'n</definitions>";
preg_match_all($re, $str, $matches);
然后您可以从$matches
抓取捕获的内容。
匹配信息:
MATCH 1
1. [53-70] `notificationInput`
MATCH 2
1. [89-93] `body`
MATCH 3
1. [108-127] `notificationRequest`
MATCH 4
1. [162-180] `notificationOutput`
MATCH 5
1. [199-203] `body`
MATCH 6
1. [218-238] `notificationResponse`