The command:
xmllint myfile.xml --xpath 'MapField2Data[#country="FR"]/*[#active!="false" or not(#active) ]'
works as expected for my xml structure
But trying to use it in an xsd, it fails to compile:
xmllint --loaddtd --noout --noent --xinclude --schema xsd/pnsConf.xsd pnsConf.xml
xsd/pnsConf.xsd:75: element selector: Schemas parser error : Element '{http://www.w3.org/2001/XMLSchema}selector', attribute 'xpath': The XPath expression 'MapField2Data[#country="FR"]/*[#active!="false" or not(#active) ]' could not be compiled.
My xsd has a proper
<xsd:selector xpath='MapField2Data[#country="FR"]/*[#active!="false" or not(#active) ]'/>
Where a simpler xpath like 'MapField2Data/*' works fine in both situations.
This looks like a bug or a missing feature in xmllint or libxml2.
Should I file a bug on the gnome bugzilla for xmllint?
Maybe there is another solution to my problem in the mean time?
I want "active" tags to be unique and ignore non-active tags in a structure such as this one:
<MapField2Data country='FR' >
<raw id='NoUnReadMails' active='true'>
<depend ref='_EndMailNotif'/>
<depend ref='_EndMailSub' />
</raw>
<raw id='NoUnReadMails' active='false'>
<depend ref='_EndMailNotif'/>
<depend ref='_EndMailSub' />
</raw>
<raw id='NoEMails' >
<depend ref='_EndMailNotif'/>
<depend ref='_EndMailSub' />
</raw>
...
Regards,
Emmanuel.
This is not a bug. xsd:selector only allows a restricted set of XPath operations. Your expression uses predicates which are not allowed. Also see this question.
Related
Is there a way to have Nokogiri not remove an ending tag to certain nodes. I have the following node, and when I write my xml file with changes I'm losing an ending tag on it:
Before my modifications, it looks like this:
<Catalog name="example" version="3"></Catalog>
After modifications:
<Catalog name="example" version="3"/>
You can use the NO_EMPTY_TAGS option:
doc.to_xml(:save_with => Nokogiri::XML::Node::SaveOptions::NO_EMPTY_TAGS)
or the rather more concise:
doc.to_xml &:no_empty_tags
When using Nokogiri, how do you suppress the insertion of self-closing tags?
How to find the Fetus Summary node using xpath?
<container flag="SEPARATE">
<relationship>CONTAINS</relationship>
<concept>
<value>125008</value>
<scheme>
<designator>DCM</designator>
</scheme>
<meaning>Fetus Summary</meaning>
</concept>
</container>
This doesn't work:
xml.xpath( '//*[.="Fetus Summary"]' )
But similar code does, when using text values without spaces. Can someone please help?
Try to use normalize-space() function, e.g.:
//*[normalize-space(.)="Fetus Summary"]
Your original code works just fine with the XML that you have shared:
require 'nokogiri'
doc = Nokogiri.XML '
<container flag="SEPARATE">
<relationship>CONTAINS</relationship>
<concept>
<value>125008</value>
<scheme>
<designator>DCM</designator>
</scheme>
<meaning>Fetus Summary</meaning>
</concept>
</container>
'
puts doc.at_xpath( '//*[.="Fetus Summary"]' )
#=> <meaning>Fetus Summary</meaning>
This works even if you have the XML declaration <?xml version="1.0" encoding="ISO-8859-1"?> at the start of the document.
My guess is that your document has whitespace characters that look like spaces or tabs but are not. From where are you getting your XML? (Over the Internet using open-uri, or from a file?) Can you please post the result of p my_xml_string to your question, which will encode any complex characters?
I've been assigned a task to do with Ruby, but as I'm new to it I'm searching over the internet for a proper solution to solve it:
I have a list of log files reports in a web page actually divided in passed or failed.
I need to take log files and convert them into a format compatible with Jenkins Junit XML File format.
Everything, the passage from log to XML has to be written in Ruby.
Any ideas?!
I looked all over the internet and found information but still have no clear ideas how to solve this.
Are there any Ruby libraries that make this easier?
Has anyone ever handled anything like this?
You don't show the format you need, and I don't know what Jenkins needs, but creating XML is easy. Unfortunately, what you want will take a book, or several articles, which is beyond the scope of Stack Overflow. Basically though...
You can use a templating system, like ERB where you create templates for your overall XML document, or Nokogiri::Builder can be used to generate XML, or you can do it old school and use simple string interpolation to create your XML.
A syslog file is typically fairly well structured, at least for the first several fields, followed by free-form text which is the output of various commands. A log file from Apache is similar, with columns of text, followed by some free-form, but easily parsable text. There are gems here and there, along with tutorials on how to parse a log, so search around and you'll find something. The idea is you want to break down each line read into text you can assign to an XML node.
Once you have your fields, you can substitute them into the template or have Ruby interpolate the variables into strings, or use Builder to add the text between the tags.
It's not really hard, but is going to take several small tasks to accomplish.
Using string interpolation, if you wanted XML like:
<xml>
<tag1>
<tag2>some text</tag2>
<tag2>some more text</tag2>
</tag1>
</xml>
You could create it like:
var1 = "some text"
var2 = "some more text"
xml = %Q{
<xml>
<tag1>
<tag2>#{var1}</tag2>
<tag2>#{var2}</tag2>
</tag1>
</xml>
}
puts xml
Similarly, if you want to use ERB:
require 'erb'
var1 = "some text"
var2 = "some more text"
template = ERB.new <<-EOF
<xml>
<tag1>
<tag2><%= var1 %></tag2>
<tag2><%= var2 %></tag2>
</tag1>
</xml>
EOF
puts template.result(binding)
Which outputs:
<xml>
<tag1>
<tag2>some text</tag2>
<tag2>some more text</tag2>
</tag1>
</xml>
Or, using Nokogiri::Builder:
require 'nokogiri'
var1 = "some text"
var2 = "some more text"
builder = Nokogiri::XML::Builder.new do |node|
node.xml {
node.tag1 {
[var1, var2].each do |t|
node.tag2(t)
end
}
}
end
puts builder.to_xml
Which outputs:
<?xml version="1.0"?>
<xml>
<tag1>
<tag2>some text</tag2>
<tag2>some more text</tag2>
</tag1>
</xml>
Under this link there is a small explanation that may help
https://pzolee.blogs.balabit.com/2012/11/jenkins-vs-junit-xml-format/
Basically you just use https://wiki.jenkins-ci.org/display/JENKINS/xUnit+Plugin
to import a XML that follows the Junit schema. You can convert XML to Junit format having the schemes.
A good description of the Junit format can be found under: llg.cubic.org/docs/junit/
I have a single file that contains multiple concatenated XML files like so:
<?xml version ... ?>
<!DOCTYPE ... >
...
<?xml version ... ?>
<!DOCTYPE ... >
...
<?xml version ... ?>
<!DOCTYPE ... >
...
Is there any way to parse the file as is, using Nokogiri, as opposed to slicing the file up?
You need to slice it into individual documents, but that is an easy thing to do.
Ruby's String.split method makes it easy. For instance if variable foo contains the text, then foo.split("<?xml version ... ?>\n") will return an array you can loop over:
foo.split("<?xml version ... ?>\n")
[
[0] "",
[1] "<!DOCTYPE ... >\n...\n",
[2] "<!DOCTYPE ... >\n...\n",
[3] "<!DOCTYPE ... >\n..."
]
Parse each of those chunks and you'll be on your way. You might need to prepend the XML DECL statement to make Nokogiri happy, but I think it'll do OK without it.
This wouldn't be a valid XML file, so you can't parse it all in one go. But you may be able to create a class that inherits from File, and has the smarts to return end-of-file when you get to the end of each XML document. With that, you should be able to open your file once, but you would still make multiple calls to your XML parser.
If the XML fragments are not very large, it may be best to slurp a fragment at at time into a string variable (perhaps using regexp), and parse that.
Given a yaml file that contains html, like this:
template : |+
<div>Hello, world</div>
Is it possible in Vim (version 7.3.087) to highlight the html portion with html syntax highlighting?
I found the post Different syntax highlighting within regions of a file, which seems to have exactly the concept I was looking for, but I cannot get it to work as expected with yaml. I'd expect to be able to do the following (as suggested in the link):
" .vimrc
" include the code from the above link
call TextEnableCodeSnip('html' ,'#{{{html' ,'#html}}}', 'SpecialComment')
Then have the yaml as, for example:
template : |+ #{{{html
<div>Hello, world</div>
#html}}}
Unfortunately this does not work as expected i.e. the html code remains entirely highlighted with yaml. I've also noted that with my configuration (MacVim 55), this doesn't work in text files either.
I'd be grateful for your thoughts or suggestions, and thank you for reading.
check out my related question: Trouble using Vim's syn-include and syn-region to embed syntax highlighting. There I am trying to embed Python within TeX, but I think the solution might work for your case, too.
I think you want to do something like this:
let b:current_syntax = ''
unlet b:current_syntax
runtime! syntax/yaml.vim
let b:current_syntax = ''
unlet b:current_syntax
syntax include #YaML syntax/yaml.vim
let b:current_syntax = ''
unlet b:current_syntax
syntax include #HTML syntax/html.vim
syntax region htmlEmbedded matchgroup=Snip start='#{{{html' end='#html}}}' containedin=#YaML contains=#HTML
hi link Snip SpecialComment
let b:current_syntax = 'yaml.html'
The block with the runtime! command might be unnecessary if your YaML is already highlighted.
You could try to add the following in your .vimrc:
autocmd BufRead,BufNewFile *.yaml setfiletype html.yaml
A yaml file will be considered to be both of type yaml and html and both syntax color scheme should be applied but I don't really know how conflicts between the two schemes are dealt with...
It looks like you want to move the start pattern to the beginning of the next line:
template : |+
#{{{html
<div>Hello, world</div>
#html}}}
More details:
I'm on WinXP, but I saw almost the same behavior that you described.
When in a file with filetype yaml, after calling TextEnableCodeSnip I didn't see a change until I moved the start pattern down the the beginning of the next line. I was able to see the syntax highlighting work in a file with no filetype though, so this still a chance this won't work for you.
I used Maxy-B's solution. My code, in particular, is a bit different so I thought to post it for posterity:
~/.vim/after/syntax/yaml.vim
let b:current_syntax = ''
unlet b:current_syntax
syntax include #HTML syntax/html.vim
syntax region htmlCode start=#^html:#hs=e+1 end=+^\w+he=s-1,me=s-1
\ contains=#HTML
let b:current_syntax = ''
unlet b:current_syntax
syntax include #TEX syntax/tex.vim
syntax region texCode start=#^tex:#hs=e+1 end=+^\w+he=s-1,me=s-1
\ contains=#TEX
This highlights the top-level YAML nodes html and tex with those respective types of code. It's not very dynamic, but it suits my purpose and this may serve as helpful guideline for someone doing something similar. It'll highlight the following as expected (or at least, as I expect it), for example:
regular: # yaml
- yaml # yaml
html:
<b>hello</b> # html
tex:
\begin{document} # tex
\end{document} # tex
the-end: may be necessary # yaml