Repository navigation
JSON representation ('value' property) #210
Copy link
Copy link
Open
Description
The return type of the 'value' property in the to_dict() varies. ( see AddressObj:AddressObjectType example)
I suggest always returning the array, in these situations.
input.xml
<stix:STIX_Package xmlns:example_namespace="http://example_namespace"
xmlns:cyboxCommon="http://cybox.mitre.org/common-2"
xmlns:cybox="http://cybox.mitre.org/cybox-2"
xmlns:cyboxVocabs="http://cybox.mitre.org/default_vocabularies-2"
xmlns:AddressObj="http://cybox.mitre.org/objects#AddressObject-2"
xmlns:stixCommon="http://stix.mitre.org/common-1"
xmlns:stixVocabs="http://stix.mitre.org/default_vocabularies-1"
xmlns:stix="http://stix.mitre.org/stix-1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=" http://cybox.mitre.org/common-2 http://cybox.mitre.org/XMLSchema/common/2.1/cybox_common.xsd http://cybox.mitre.org/cybox-2 http://cybox.mitre.org/XMLSchema/core/2.1/cybox_core.xsd http://cybox.mitre.org/default_vocabularies-2 http://cybox.mitre.org/XMLSchema/default_vocabularies/2.1/cybox_default_vocabularies.xsd http://cybox.mitre.org/objects#AddressObject-2 http://cybox.mitre.org/XMLSchema/objects/Address/2.1/Address_Object.xsd http://stix.mitre.org/common-1 http://stix.mitre.org/XMLSchema/common/1.1.1/stix_common.xsd http://stix.mitre.org/default_vocabularies-1 http://stix.mitre.org/XMLSchema/default_vocabularies/1.1.1/stix_default_vocabularies.xsd http://stix.mitre.org/stix-1 http://stix.mitre.org/XMLSchema/core/1.1.1/stix_core.xsd" version="1.1.1">
<stix:Observables cybox_major_version="2" cybox_minor_version="1" cybox_update_version="0">
<cybox:Observable id="example_namespace:Observable-de76dce6-22a9-4709-9924-9eab9b7f531b">
<cybox:Title>IPs</cybox:Title>
<cybox:Object id="example_namespace:Object-140d93f8-7bd9-4b23-b3bf-6cc3be8d7b28">
<cybox:Properties xsi:type="AddressObj:AddressObjectType" category="ipv4-addr">
<AddressObj:Address_Value condition="Equals" is_case_sensitive="false" apply_condition="ANY" delimiter="##example_namespace##">1.1.1.1##example_namespace##2.2.2.2##example_namespace##3.3.3.3</AddressObj:Address_Value>
</cybox:Properties>
</cybox:Object>
</cybox:Observable>
<cybox:Observable id="example_namespace:Observable-8442aae7-0a38-4d6e-ae99-12ed42402a22">
<cybox:Title>ip</cybox:Title>
<cybox:Object id="example_namespace:Object-dbf87db5-fad7-4492-bf2e-b0a4b82e1d14">
<cybox:Properties xsi:type="AddressObj:AddressObjectType" category="ipv4-addr">
<AddressObj:Address_Value condition="Equals" is_case_sensitive="false" apply_condition="ANY" delimiter="##example_namespace##">0.0.0.0</AddressObj:Address_Value>
</cybox:Properties>
</cybox:Object>
</cybox:Observable>
</stix:Observables>
</stix:STIX_Package>script.py
#!/usr/bin/env python
# Copyright (c) 2014, The MITRE Corporation. All rights reserved.
# See LICENSE.txt for complete terms.
'''
File: ex_01.py
Description: Round-trip example. This script takes a STIX instance document from XML to
a binding object, then to a api object and then to a dictionary. That dictionary is then
converted back into an api object, which is then used to generate an XML document.
'''
import io
from pprint import pprint
from stix.core import STIXPackage
def main():
fn = 'input.xml'
stix_package = STIXPackage.from_xml(fn)
stix_dict = stix_package.to_dict() # parse to dictionary
pprint(stix_dict)
stix_package_two = STIXPackage.from_dict(stix_dict) # create python-stix object from dictionary
xml = stix_package_two.to_xml() # generate xml from python-stix object
print(xml)
if __name__ == '__main__':
main()output.json
{
"observables": {
"observables": [
{
"object": {
"id": "example_namespace:Object-140d93f8-7bd9-4b23-b3bf-6cc3be8d7b28",
"properties": {
"category": "ipv4-addr",
"xsi:type": "AddressObjectType",
"address_value": {
"apply_condition": "ANY",
"delimiter": "##example_namespace##",
"is_case_sensitive": false,
"condition": "Equals",
"value": [
"1.1.1.1",
"2.2.2.2",
"3.3.3.3"
]
}
}
},
"id": "example_namespace:Observable-de76dce6-22a9-4709-9924-9eab9b7f531b",
"title": "IPs"
},
{
"object": {
"id": "example_namespace:Object-dbf87db5-fad7-4492-bf2e-b0a4b82e1d14",
"properties": {
"category": "ipv4-addr",
"xsi:type": "AddressObjectType",
"address_value": {
"delimiter": "##example_namespace##",
"is_case_sensitive": false,
"condition": "Equals",
"value": "0.0.0.0"
}
}
},
"id": "example_namespace:Observable-8442aae7-0a38-4d6e-ae99-12ed42402a22",
"title": "ip"
}
],
"major_version": 2,
"update_version": 0,
"minor_version": 1
},
"version": "1.1.1"
}Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Activity
bworrell commentedon Oct 10, 2014
@marlontaylor,
The values vary because you aren't always representing a list of values. Sometimes you are passing along a single value. I understand that you are suggesting that we always use lists there, even if that list has a single value, though I'm not sure if there are undesired consequences to changing this.
We can look into doing this on the JSON/dict side of things, but for API object instances, you can use the
valuesproperty on object fields to always return a list of values (even if there is only one property value).gtback commentedon Oct 15, 2014
I think that always including a list is a bad idea, particularly for CybOX instances, which can never use a list of values. It might be alright to always use them for patterns, but it will still require applications other than python-cybox to do some conditional parsing—python-cybox already takes care of this here.
On a related note, we probably don't need to include the
delimiterin the dictionary, since we are using a native JSON list rather than a delimited string. That does mean we need to add some logic to choose a new delimiter if it was deliberately set to allow representing the literal string "##comma##". Right now it just raises aValueError.