我有一个xml文档,如下所示:
<menuitem navigateurl="/PressCentre/" text="прес център">
<menuitem navigateurl="/PressCentre/RegisterForPressAlerts/" text="регистър за прес съобщения" />
<menuitem navigateurl="/PressCentre/PressReleases/" text="прес съобщения">
<menuitem navigateurl="/PressCentre/PressReleases/PressReleasesArchive/" text="архив прес съобщения" />
</menuitem>
<menuitem navigateurl="/PressCentre/PressKit/" text="прес комплект">
<menuitem navigateurl="/PressCentre/PressKit/FactSheets/" text="списък факти" />
<menuitem navigateurl="/PressCentre/PressKit/ExpertComments/" text="коментари на експерти" />
<menuitem navigateurl="/PressCentre/PressKit/Testimonials/" text="препоръки" />
<menuitem navigateurl="/PressCentre/PressKit/MediaFiles/" text="медия файлове" />
<menuitem navigateurl="/PressCentre/PressKit/Photography/" text="снимки" />
</menuitem>
<menuitem navigateurl="/PressCentre/PressContacts/" text="прес контакти" />
</menuitem>
我需要获取navigateurl之间的值(例如“/ PressCentre”)。是否有一个众所周知的正则表达式脚本来执行此操作?
由于
答案 0 :(得分:6)
一个基本的递归(未经测试,但我认为没关系):
private void Caller(String filepath)
{
XPathDocument oDoc = new XPathDocument(filepath);
Readnodes( oDoc.CreateNavigator() );
}
private void ReadNodes(XPathNavigator nav)
{
XPathNodeIterator nodes = nav.Select("menuitem");
while (nodes.MoveNext())
{
//A - read the attribute
string url = nodes.Current.GetAttribute("navigateurl", string.Empty);
//B - do something with the data
//C - recurse
ReadNodes(nodes.Current);
}
}
...因为XPathNodeIterator的Current属性也是XPathNavigator而起作用。显然,你需要扩展它以将数据推送到字典或跟踪深度或其他任何内容。
答案 1 :(得分:1)
为什么在XPath(对我来说,至少是)自然选择的时候使用正则表达式呢?这基本上就是XSLT应该实现的......
答案 2 :(得分:0)
您使用正则表达式的任何特殊原因?您是否尝试过使用XPath?以下是如何使用XPath的一些示例。 http://www.w3schools.com/XPath/xpath_examples.asp
答案 3 :(得分:0)
使用xpath,// menuitem [@navigateurl] / @ navigateurl。
此xpath将获取具有属性naviagate url的所有菜单项,并返回navigationurl值的节点列表(xpath 1.0)或序列(xpath 2.0)。通过使用navigateurl属性谓词,可确保仅提取叶子菜单项。
答案 4 :(得分:0)
我的帖子解决了与OP的调查相关的特定需求,但没有具体说明OP所询问的内容。当我需要它时,我喜欢正则表达式和递归,但在这种情况下,我认为OP的调查的目的是学习一种生成格式正确的XML输出的方法,而我在下面提供的内容确实没有重大的上下文源代码开发(为什么要重新发明轮子?)并在.NET 2.0框架中得到支持。
在我的工作中,我经常最终支持现代政府系统。这些系统通常仍然只支持部署系统上的2.0 - 主要是出于安全考虑。 2.0 Framework缺少最新.NET版本的一些优雅输出,特别是在涉及XML对象的情况下。下面完全验证的方法集对我来说非常有价值且节省时间,我为那些也为政府利益服务的看不见的开发者同志提供了这些方法。
此外,您还可以利用LinqBridge库获得有限的Linq支持(.NET up到3.5 service-pack实际上内部自我评估为2.0,因此构建LinqBridge以弥合特定差距(开发到2.0版本时,Linq查询支持有限)使用Visual Studio 2008。但请注意,LinqBridge目前不支持Visual Studio 2008。
为了最小化包发布大小并且与我提供服务的组织要求保持兼容,我避免使用关联非XML库(例如Regex)来解析XML并坚持使用标准XML对象。特别是较旧的Xml * -prefix对象与更现代(和更灵活)的X * -prefix对象...
下面我提供了许多安全,简单,高效的方法,可以从各种标准的2.0 Xml *对象生成格式化的XML。还要注意,这些函数的主力实际上是XPathNavigator类,而不是它的表兄弟。
这是一个调用示例方法的C#代码片段:
doc = new XmlDocument();
doc.Load(Input_FilePath);
sb = StringBuilderFromXmlDocument(doc);
Out(sb);
sb = StringBuilderFromXPathDocument(new XPathDocument(Input_FilePath));
Out(sb);
sb = StringBuilderFromXPathNavigator(new XPathDocument(Input_FilePath).CreateNavigator());
Out(sb);
ss = StringFromXmlDocument(doc);
Out(ss);
ss = StringFromXPathDocument(new XPathDocument(Input_FilePath));
Out(ss);
ss = StringFromXPathNavigator(new XPathDocument(Input_FilePath).CreateNavigator());
Out(ss);
以下是示例方法,其中一个方法可能满足您的XML格式需求:
public static StringBuilder StringBuilderFromXmlDocument(XmlDocument _xd)
{
XPathNavigator _xpn;
try
{
_xpn = _xd.CreateNavigator();
}
catch
{
_xd.LoadXml(DEFAULT_ERROR_TEXT);
_xpn = _xd.CreateNavigator();
}
return StringBuilderFromXPathNavigator(_xpn);
}
private static StringBuilder StringBuilderFromXPathDocument(XPathDocument _xpd)
{
StringBuilder returnVal = new StringBuilder();
XPathNavigator _xpn;
try
{
_xpn = _xpd.CreateNavigator();
returnVal.AppendLine(_xpn.OuterXml.Trim());
}
catch
{
returnVal = new StringBuilder()
.Append(DEFAULT_ERROR_TEXT);
}
return returnVal;
}
private static StringBuilder StringBuilderFromXPathNavigator(XPathNavigator _xpn)
{
StringBuilder returnVal = new StringBuilder();
try
{
returnVal.AppendLine(_xpn.OuterXml.Trim());
}
catch
{
returnVal = new StringBuilder()
.Append(DEFAULT_ERROR_TEXT);
}
return returnVal;
}
public static string StringFromXmlDocument(XmlDocument _xd)
{
XPathNavigator _xpn;
try
{
_xpn = _xd.CreateNavigator();
}
catch
{
_xd.LoadXml(DEFAULT_ERROR_TEXT);
_xpn = _xd.CreateNavigator();
}
return StringFromXPathNavigator(_xpn);
}
private static string StringFromXPathNavigator(XPathNavigator _xpn)
{
string returnVal;
try
{
returnVal = _xpn.OuterXml.Trim();
}
catch
{
returnVal = DEFAULT_ERROR_TEXT;
}
returnVal = _xpn.OuterXml.Trim();
return returnVal;
}
private static string StringFromXPathDocument(XPathDocument _xpd)
{
string returnVal;
XPathNavigator _xpn;
try
{
_xpn = _xpd.CreateNavigator();
returnVal = _xpn.OuterXml.Trim();
}
catch
{
returnVal = DEFAULT_ERROR_TEXT;
}
return returnVal;
}
享受。 ^^
请注意,在以后的Framework版本中并使用较新的XElement对象,您可以foreach(){} XElement的节点和.ToString()每个结果以自动正确格式化。就像我上面说的那样,更加优雅:)。
答案 5 :(得分:0)
如何使用Java中的正则表达式递归读取XML文档
public static void main(String[] args) {
String data**="<CheckExistingDSLService>" +
"<DSLPN>4137361787</DSLPN>" +
"<DSLPN>8566944014</DSLPN>" +
"<ClientRequestId>CRID</ClientRequestId>" +
"<DSLPN>8566944024</DSLPN>" +
"<ClientSystemId>SSPORD</ClientSystemId>" +
"<Authentication>" +
"<Id>SSPORD</Id>" +
"</Authentication>" +
"<Comment>Service to check CheckExistingDSL</Comment>"** +
"</CheckExistingDSLService>";
System.out.print("The dats is "+listDataElements(data));
}
private static final Pattern PATTERN_1 = Pattern.compile("<([^<>]+)>([^<>]+)</\\1>");
private static List<String> listDataElements(CharSequence cs) {
List<String> list = new ArrayList<String>();
Matcher matcher = PATTERN_1.matcher(cs);
while (matcher.find()) {
if(matcher.group(1).equalsIgnoreCase("DSLPN")){
try{
Long number=Long.parseLong(matcher.group(2));
list.add(number.toString());
}catch(Exception e){
System.out.println("Do noting this is notnumber ");
}
}
} return list;
}
您将获得的输出:日期为[4137361787,8566944014,8566944024]