编辑根据@Gert Arnold的建议,我决定编辑并更彻底地格式化我的问题。
我一直在尝试通过Linq选择传递id和value条件的节点。在我的情况下,我需要series
在value
节点中具有两个特定SeriesKey
属性的节点。
这是我的XML字符串(仅供参考,如果您发现任何标记错误,可能是由于我的缩进错误,原始文件 XML有效)
<message:GenericData xmlns:footer="http://www.sdmx.org/resources/sdmxml/schemas/v2_1/message/footer"
xmlns:generic="http://www.sdmx.org/resources/sdmxml/schemas/v2_1/data/generic"
xmlns:message="http://www.sdmx.org/resources/sdmxml/schemas/v2_1/message"
xmlns:common="http://www.sdmx.org/resources/sdmxml/schemas/v2_1/common"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<message:DataSet>
<generic:Series>
<generic:SeriesKey>
<generic:Value id="GEO" value="124"/>
<generic:Value id="PRODUCT" value="4400"/>
<generic:Value id="FIN" value="03"/>
<generic:Value id="ENERGY_UNITS" value="WSR"/>
</generic:SeriesKey>
<generic:Obs>
<generic:ObsDimension id="TIME_PERIOD" value="1999"/>
<generic:ObsValue value="0"/>
<generic:Attributes>
<generic:Value id="UNIT_SUFFIX" value="R"/>
</generic:Attributes>
</generic:Obs>
<generic:Obs>
<generic:ObsDimension id="TIME_PERIOD" value="2000"/>
<generic:ObsValue value="0"/>
<generic:Attributes>
<generic:Value id="UNIT_SUFFIX" value="R"/>
</generic:Attributes>
</generic:Obs>
</generic:Series>
<generic:Series>
<generic:SeriesKey>
<generic:Value id="GEO" value="124"/>
<generic:Value id="PRODUCT" value="4100"/>
<generic:Value id="FIN" value="03"/>
<generic:Value id="ENERGY_UNITS" value="WSR"/>
</generic:SeriesKey>
<generic:Obs>
<generic:ObsDimension id="TIME_PERIOD" value="1999"/>
<generic:ObsValue value="8246"/>
<generic:Attributes>
<generic:Value id="UNIT_SUFFIX" value="R"/>
</generic:Attributes>
</generic:Obs>
<generic:Obs>
<generic:ObsDimension id="TIME_PERIOD" value="2000"/>
<generic:ObsValue value="40733"/>
<generic:Attributes>
<generic:Value id="UNIT_SUFFIX" value="R"/>
</generic:Attributes>
</generic:Obs>
</generic:Series>
<generic:Series>
<generic:SeriesKey>
<generic:Value id="GEO" value="124"/>
<generic:Value id="PRODUCT" value="4200"/>
<generic:Value id="FIN" value="03"/>
<generic:Value id="ENERGY_UNITS" value="WSR"/>
</generic:SeriesKey>
<generic:Obs>
<generic:ObsDimension id="TIME_PERIOD" value="1999"/>
<generic:ObsValue value="279"/>
<generic:Attributes>
<generic:Value id="UNIT_SUFFIX" value="R"/>
</generic:Attributes>
</generic:Obs>
<generic:Obs>
<generic:ObsDimension id="TIME_PERIOD" value="2000"/>
<generic:ObsValue value="324"/>
<generic:Attributes>
<generic:Value id="UNIT_SUFFIX" value="R"/>
</generic:Attributes>
</generic:Obs>
</generic:Series>
</message:DataSet>
</message:GenericData>
我尝试使用查询方式,只需使用逻辑运算符创建一系列步骤,如where
语句中所示。我附上了有问题的方法。此时它接受xml字符串(上面一个)和两个过滤条件,即EnergyProduct
来过滤PRODUCT
属性,EconSector
来过滤FIN
属性。
public IEnumerable<XElement> DataSetFilter(string XmlString, string EnergyProduct, string EconSector)
{
XDocument sdmx_response = XDocument.Parse(XmlString);
XNamespace message = "http://www.sdmx.org/resources/sdmxml/schemas/v2_1/message";
XNamespace generic = "http://www.sdmx.org/resources/sdmxml/schemas/v2_1/data/generic";
IEnumerable<XElement> DataSet = sdmx_response.Root.Elements(message + "DataSet");
IEnumerable<XElement> Series = from series in DataSet.Elements(generic + "Series")
from serieskey in series.Elements(generic + "SeriesKey")
from value in serieskey.Elements(generic + "Value")
where
(
(string)value.Attribute("id") == "PRODUCT" && (string)value.Attribute("value") == EnergyProduct
) ||
(
(string)value.Attribute("id") == "FIN" && (string)value.Attribute("value") == EconSector
)
select serieskey;
IEnumerable <XElement> observationsSet = from observations in Series.Elements(generic + "Obs").Elements(generic + "ObsValue") select observations;
return observationsSet;
}
问题是它抓取了两个属性的所有数据,例如那些匹配PRODUCT
代码“4400”和FIN
代码“03”的数据,而我正在寻找的只是包含具有这些精确值的子节点的节点,两者都在同一SeriesKey
中。我正在考虑创建一个包含我想要的xml元素的匿名对象,但是我遇到了错误,我仍然对如何正确实现它感到困惑。
谢谢你的帮助!
答案 0 :(得分:2)
尝试以下:
public class MainActivity extends Activity {
private Button b;
public TextView t;
public TextView u;
public TextView add;
private LocationManager locationManager;
private LocationListener listener;
public Button b2;
private EditText e;
double LATITUDE;
double LONGITUDE;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
t = (TextView) findViewById(R.id.textView);
u = (TextView) findViewById(R.id.textView3);
add = (TextView) findViewById(R.id.textView4);
b = (Button) findViewById(R.id.button);
b2 = (Button) findViewById(R.id.button2);
e = (EditText) findViewById(R.id.editText);
b2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String number = e.getText().toString();
String loc = t.getText().toString();
String loc1 = u.getText().toString();
String loc2 = add.getText().toString();
Intent sendIntent = new Intent(Intent.ACTION_VIEW);
sendIntent.setData(Uri.parse("sms:"+number));
sendIntent.putExtra("sms_body",loc+loc1+loc2);
try {
startActivity(sendIntent);
finish();
Log.i("Finished sending SMS...", "");
}
catch (android.content.ActivityNotFoundException ex) {
Toast.makeText(MainActivity.this,
"SMS failed, please try again later.", Toast.LENGTH_SHORT).show();
}
}
});
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
listener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
t.append("\n " + location.getLatitude());
u.append("\n " + location.getLongitude());
}
@Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
@Override
public void onProviderEnabled(String s) {
}
@Override
public void onProviderDisabled(String s) {
Intent i = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(i);
}
};
configure_button();
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode){
case 10:
configure_button();
break;
default:
break;
}
}
void configure_button(){
// first check for permissions
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION,Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.INTERNET}
,10);
}
return;
}
// this code won't execute IF permissions are not allowed, because in the line above there is return statement.
b.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//noinspection MissingPermission
locationManager.requestLocationUpdates("gps",15000,0, listener);
}
});
}
public void phone(View view) {
Intent i = new Intent(this,Main2Activity.class);
startActivity(i);
}
public void address(View view) {
LATITUDE = Double.parseDouble(t.getText().toString());
LONGITUDE = Double.parseDouble(u.getText().toString());
Geocoder geocoder = new Geocoder(this, Locale.ENGLISH);
String result;
try {
List<Address> addressList = geocoder.getFromLocation(LATITUDE, LONGITUDE, 1);
if (addressList != null && addressList.size() > 0) {
Address address = addressList.get(0);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < address.getMaxAddressLineIndex(); i++) {
sb.append(address.getAddressLine(i));
}
sb.append("\n" + address.getLocality());
sb.append("\n" + address.getPostalCode());
sb.append("\n" + address.getCountryName());
result = sb.toString();
add.append(result);
}
}
catch (IOException e) {
}
}
}
答案 1 :(得分:0)
我赞成并选择了jdweng的答案作为最合适的解决方案。这是我的代码。
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = @"c:\temp\test.xml";
static void Main(string[] args)
{
IEnumerable<XElement> NormalizedDataSet = NormalizeGeneric(FILENAME);
foreach (XElement Series in NormalizedDataSet)
{
Console.WriteLine(Series);
}
}
public IEnumerable<XElement> NormalizeGeneric(string XmlString)
{
XDocument xml_response = XDocument.Parse(XmlString);
XNamespace message = "http://www.sdmx.org/resources/sdmxml/schemas/v2_1/message";
XNamespace generic = "http://www.sdmx.org/resources/sdmxml/schemas/v2_1/data/generic";
XElement SeriesSet = xml_response.Root;
IEnumerable<XElement> SeriesObject = seriesSet.Elements(message + "DataSet")
.Elements(generic + "Series")
.Select(series => new XElement("Series", new object[]
{
new XElement("Metadata",
series.Elements(generic + "SeriesKey")
.Elements(generic + "Value")
.Select(value => new XElement((string)value.Attribute("id"), new XAttribute("value", (string)value.Attribute("value"))))),
new XElement("Data",
series.Elements(generic + "Obs")
.Select(observations => new XElement("Observation", new XAttribute((string)observations.Element(generic + "ObsDimension")
.Attribute("id"), (string)observations.Element(generic + "ObsDimension").Attribute("value")), new XAttribute("value", (string)observations.Element(generic + "ObsValue").Attribute("value")), new XElement("Attributes", observations.Elements(generic + "Attributes").Elements(generic + "Value").Select(attributes => new XElement((string)attributes.Attribute("id"), new XAttribute("value", (string)attributes.Attribute("value"))))))))
})).ToArray();
return SeriesObject;
}
}
}
我的代码与jdweng的区别在于,我还添加了包含实际数字的文件的数据部分。正常化&#39;数据集的数据集是不可避免的,因此更容易操作值并过滤必要的节点。感谢您对迟到的反应和缩进道歉。