How to parse XML and get instances of a particular node attribute?
I suggest ElementTree
. There are other compatible implementations of the same API, such as lxml
, and cElementTree
in the Python standard library itself; but, in this context, what they chiefly add is even more speed -- the ease of programming part depends on the API, which ElementTree
defines.
First build an Element instance root
from the XML, e.g. with the XML function, or by parsing a file with something like:
import xml.etree.ElementTree as ET
root = ET.parse('thefile.xml').getroot()
Or any of the many other ways shown at ElementTree
. Then do something like:
for type_tag in root.findall('bar/type'):
value = type_tag.get('foobar')
print(value)
Output:
1
2
C# Parse XML & action if attribute of node matches a string
You misunderstood the attribute ToString()
function. The way you do it you are comparing the string of the class name "System.Xml.XmlAttribute" instead of the actual value you wanted. So assuming all of your other code works this should work
foreach (XmlNode node in ParseExistingKingdomXML_xDoc.DocumentElement)
{
if (node.Name == "Kingdom")
{
var attribute = node.Attributes["title"].Value;
if (attribute == XMLExistingKingdomsStrings.KingdomName) {
XMLExistingKingdomsStrings.KingdomID = node.Attributes["title"].Value;
}
}
}
How to search for a Xml node with a given attribute value in python
xml.etree.ElementTree
provides only limited support for XPath expressions for locating elements in a tree, and that doesn't include xpath contains()
function. See the documentation for list of supported xpath syntax.
You need to resort to a library that provide better xpath support, like lxml, or use simpler xpath and do further filtering manually, for example :
import xml.etree.ElementTree as ET
tree = ET.parse('test.xml')
root = tree.getroot()
list = filter(lambda x: 'Pana' in x.get('name'), root.findall(".//country[@name]"))
Parse XML based on node attribute and edit when found
Here's a suggested approach using a scripting dictionary to track what sections have already been added, so we can easily get a reference to the required element to which the description needs to be added/appended.
Option Explicit
Sub RPCTranslatesCombinedInfoBackwardsChecking()
Const THE_NS As String = "urn:Riwo.Pcs.Localization"
Dim oXMLDoc As Object, oRoot As Object, dict As Object, sSectionPrefix As String
Dim sSectionName As String, sDescription As String, txt, oPI As Object, lRow As Long
Dim oElmSection As Object, dictKey As String, oElmTranslation As Object
Set dict = CreateObject("scripting.dictionary")
Set oXMLDoc = CreateObject("MSXML2.DOMDocument")
Set oPI = oXMLDoc.createProcessingInstruction("xml", "version=""1.0"" encoding=""UTF-8""")
'create the root element
Set oRoot = CreateWithAttributes(oXMLDoc, "Translations", THE_NS, "", _
Array("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance", _
"xmlns:xsd", "http://www.w3.org/2001/XMLSchema", _
"code", "nl", _
"description", "Dutch")) '
oXMLDoc.appendchild oRoot
lRow = 2
With ActiveSheet
Do While .Cells(lRow, 4).Value <> ""
sSectionPrefix = Right(.Cells(lRow, 1).Value, Len(.Cells(lRow, 1).Value) - 1)
sSectionName = .Cells(lRow, 4).Value
dictKey = sSectionPrefix & "." & sSectionName
'first time seeing this section name? - add to document and to dictionary
If Not dict.exists(dictKey) Then
Set oElmSection = CreateWithAttributes(oXMLDoc, "Section", THE_NS, "", _
Array("name", dictKey))
oRoot.appendchild oElmSection
Set oElmTranslation = CreateWithAttributes(oXMLDoc, "Translation", THE_NS, "", _
Array("key", "Info"))
oElmSection.appendchild oElmTranslation
Set dict(dictKey) = oElmTranslation 'store reference in dictionary
End If
Set oElmTranslation = dict(dictKey) 'get the node to add content
sDescription = .Cells(lRow, 1).Value & " " & .Cells(lRow, 2).Value & " " & _
.Cells(lRow, 3).Value & " " & .Cells(lRow, 5).Value
txt = oElmTranslation.Text
If Len(txt) > 0 Then txt = txt & "[br]"
txt = txt & sDescription
oElmTranslation.NodetypedValue = txt
lRow = lRow + 1
Loop
End With
Debug.Print oXMLDoc.XML
oXMLDoc.Save "C:\Users\thomas.RIWO\Desktop\Translations\RPC test\test2.xml"
End Sub
Having previously done a bunch of XML creation, I find it's much easier to see what you're doing if you factor out the repetitive parts into a separate utility method such as the one shown below. It's quite basic, but covers a lot of what you need to do while constructing an XML document.
'Utility method: create and return an element, with
' optional namespace, value and attributes
Function CreateWithAttributes(doc As Object, elName As String, _
elNameSpace As String, elValue As String, Optional attr As Variant = Empty)
Dim el, u, i As Long, att As Object, txt As Object
'create the node
Set el = doc.CreateNode(1, elName, elNameSpace)
'if have attributes, loop and add
If Not IsEmpty(attr) Then
For i = 0 To UBound(attr) Step 2
Set att = doc.CreateAttribute(attr(i))
att.Value = attr(i + 1)
el.Attributes.setNamedItem att
Next i
End If
'any element content to add?
If Len(elValue) > 0 Then
Set txt = doc.createTextNode(elValue)
el.appendchild txt
End If
Set CreateWithAttributes = el
End Function
Parse XML with Attributes
As the error tells you, you haven't defined the singleton, which defines what numbered node the value is from. Most likely you just want the 1st node. I also changed your data types, as I doubt your values could all be up to 1 billion characters long (though I use an nvarchar(2)
for most, which may not be long enough in all places).
This gives something like the following:
DECLARE @XML xml = '<someStructure>
<Tag1 Qualifier = "QQ" Name = "Name">
<Tag2 Code = "CD" Name = "SomeName">
<Tag3 Qualifier = "QW" Number = "22"/>
</Tag2>
</Tag1>
<Tag1 Qualifier = "NN" Name = ""/>
<Tag1 Qualifier = "QE" Name = "Name2">
<Tag2 Code = "CD" Name = "SomeName2">
<Tag3 Qualifier = "QW" Number = "22"/>
</Tag2>
</Tag1>
</someStructure>';
SELECT sS.T1.value('(@Qualifier)[1]','nvarchar(2)') AS Tag1Qualifier, --Does this "need" to be up to 1 billion characters long?
sS.T1.value('(@Name)[1]','nvarchar(20)') AS Tag1Name, --Does this "need" to be up to 1 billion characters long?
sS.T1.value('(Tag2/@Code)[1]','nvarchar(2)') AS Tag2Code, --Does this "need" to be up to 1 billion characters long?
sS.T1.value('(Tag2/@Name)[1]','nvarchar(20)') AS Tag2Name, --Does this "need" to be up to 1 billion characters long?
sS.T1.value('(Tag2/Tag3/@Qualifier)[1]','nvarchar(2)') AS Tag3Qualifier, --Does this "need" to be up to 1 billion characters long?
sS.T1.value('(Tag2/Tag3/@Number)[1]','int') AS Tag3Number --Does this "need" to be up to 1 billion characters long?
FROM (VALUES(@XML))V(X)
CROSS APPLY V.X.nodes('/someStructure/Tag1') sS(T1);
How to parse an XML element that has an attribute inside it? Asp.net C#
Use XDocument instead of XmlReader much easier to query.
first example
some code where you have too loop thru the results that did return from the LINQ query. But since you only have one < time > element and one < temperature > element inside that you can better use the second example
// Create XDocument and load in the file
XDocument _doc = XDocument.Load("C:\\t\\My File2.txt");
//select all time element where attribute day.Value == to any day you give it just change "2017-04-18"
var time = _doc.XPathSelectElements("/weatherdata/forecast/time").Where(c => c.Attribute("day").Value == "2017-04-18");
// Get IEnumerable of temperatures in the time element
var temp = time.Select(x => x.Element("temperature"));
// loop temperatures and get the attribute value from the element
foreach (var element in temp)
{
string day = element.Attribute("day").Value;
string min = element.Attribute("min").Value;
string max = element.Attribute("max").Value;
string night = element.Attribute("night").Value;
string eve = element.Attribute("eve").Value;
string morn = element.Attribute("morn").Value;
MessageBox.Show($"day:{day},\nmin:{min},\nmax:{max},\nnight:{night},\neve:{eve},\nmorn:{morn}");
}
Second example
I get the first one of a query result, so you don't have to loop to get one element. It is a bit riskier because you can get a null reference exception when no elements are found. but by a simple if you can catch it before it will be thrown.
// Create XDocument and load in the file my case it is the path "C:\\t\\My File2.txt"
XDocument _doc = XDocument.Load("C:\\t\\My File2.txt");
// Select all time elements where attribute day.Value == to any day you give it, just change "2017-04-18"
// And select the first one of that result as I aspect there is only one time a day
var time = _doc.XPathSelectElements("/weatherdata/forecast/time").Where(c => c.Attribute("day").Value == "2017-04-18").FirstOrDefault();
// Get the children of time element by using .Elements() and take the first one of that.
// You only have one temperature element in a time element so it will take that one with FirstOrDefault();
var temp = time.Elements().FirstOrDefault();
// assign attributes values to string
string day = temp.Attribute("day").Value;
string min = temp.Attribute("min").Value;
string max = temp.Attribute("max").Value;
string night = temp.Attribute("night").Value;
string eve = temp.Attribute("eve").Value;
string morn = temp.Attribute("morn").Value;
// control
MessageBox.Show($"day:{day},\nmin:{min},\nmax:{max},\nnight:{night},\neve:{eve},\nmorn:{morn}");
Result with day "2017-04-18":
How to parse the attribute value of a specific tag of an xml file which has multiple occurrences through Lua?
LuaXML seems to be pretty minimal and xml.find
states:
Returns the first (sub-)table which matches the search condition or
nil.
A simpler solution would be using Lua string pattern:
local file = io.open("oem.xml", "rb") -- Open file for reading (binary data)
for name, value in file:read("*a"):gmatch("<Attribute name=\"(.-)\" value=\"(.-)\" />") do -- Read whole file content and iterate through attribute matches
print(string.format("Name: %s\nValue: %s", name, value)) -- Print what we got
end
file:close() -- Close file (for instant lock-free, no waiting for garbage collector)
Don't forget to check file
for being valid.
Related Topics
Relative Imports For the Billionth Time
What Are Metaclasses in Python
How to Read a File Line-By-Line into a List
How to Serve Static Files in Flask
Of the Many Findelement(S)/By Functions in Selenium, When Would You Use One Over the Other
Are Global Variables Thread-Safe in Flask? How to Share Data Between Requests
Selenium "Selenium.Common.Exceptions.Nosuchelementexception" When Using Chrome
How to Import a Module Given the Full Path
How to List All Files of a Directory
How to Add to the Pythonpath in Windows, So It Finds My Modules/Packages
Syntax Error on Print With Python 3
How to Iterate Over a List in Chunks